mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76172fd27e | ||
|
|
c145388dd2 | ||
|
|
faa3dc7654 | ||
|
|
3f0dd063cb | ||
|
|
c2184ad4ff | ||
|
|
31cd9d1f61 | ||
|
|
ca6bd89a69 | ||
|
|
82b648e491 | ||
|
|
085363db07 | ||
|
|
565988c96f | ||
|
|
2977fc4025 | ||
|
|
1ded991603 | ||
|
|
dc19cd2c9d | ||
|
|
945f1c7262 | ||
|
|
70255b1db1 | ||
|
|
c96d7db592 | ||
|
|
6780e671f9 | ||
|
|
e5799c1dc2 | ||
|
|
6544cec686 |
@@ -75,10 +75,6 @@ executors:
|
||||
resource_class: << parameters.size >>
|
||||
|
||||
# Electron Runners
|
||||
apple-silicon:
|
||||
resource_class: electronjs/macos-arm64
|
||||
machine: true
|
||||
|
||||
linux-arm:
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
@@ -2331,8 +2327,11 @@ jobs:
|
||||
- electron-tests:
|
||||
artifact-key: darwin-x64
|
||||
|
||||
darwin-testing-arm64-tests:
|
||||
executor: apple-silicon
|
||||
darwin-testing-arm64-tests:
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.m1.medium.gen1
|
||||
version: 14.0.0
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
@@ -2356,7 +2355,10 @@ jobs:
|
||||
artifact-key: mas-x64
|
||||
|
||||
mas-testing-arm64-tests:
|
||||
executor: apple-silicon
|
||||
executor:
|
||||
name: macos
|
||||
size: macos.m1.medium.gen1
|
||||
version: 14.0.0
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-stack-dumping
|
||||
|
||||
@@ -112,4 +112,4 @@ and more can be found on the [Community page](https://www.electronjs.org/communi
|
||||
|
||||
[MIT](https://github.com/electron/electron/blob/main/LICENSE)
|
||||
|
||||
When using Electron logos, make sure to follow [OpenJS Foundation Trademark Policy](https://openjsf.org/wp-content/uploads/sites/84/2021/01/OpenJS-Foundation-Trademark-Policy-2021-01-12.docx.pdf).
|
||||
When using Electron logos, make sure to follow [OpenJS Foundation Trademark Policy](https://trademark-policy.openjsf.org/).
|
||||
|
||||
@@ -77,6 +77,7 @@ template("electron_extra_paks") {
|
||||
"//content:content_resources",
|
||||
"//content/browser/resources/gpu:resources",
|
||||
"//content/browser/resources/media:resources",
|
||||
"//content/browser/resources/process:resources",
|
||||
"//content/browser/tracing:resources",
|
||||
"//content/browser/webrtc/resources",
|
||||
"//electron:resources",
|
||||
@@ -96,6 +97,7 @@ template("electron_extra_paks") {
|
||||
# New paks should be added here by default.
|
||||
sources += [
|
||||
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
|
||||
"$root_gen_dir/content/process_resources.pak",
|
||||
"$root_gen_dir/ui/resources/webui_resources.pak",
|
||||
]
|
||||
deps += [ "//content/browser/devtools:devtools_resources" ]
|
||||
|
||||
@@ -262,13 +262,11 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
|
||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||
// print param logic into new file shared between printToPDF and print
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
|
||||
if (typeof options !== 'object') {
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions = {}, callback) {
|
||||
if (typeof options !== 'object' || options == null) {
|
||||
throw new TypeError('webContents.print(): Invalid print settings specified.');
|
||||
}
|
||||
|
||||
const printSettings: Record<string, any> = { ...options };
|
||||
|
||||
const pageSize = options.pageSize ?? 'A4';
|
||||
if (typeof pageSize === 'object') {
|
||||
if (!pageSize.height || !pageSize.width) {
|
||||
@@ -282,7 +280,7 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
throw new RangeError('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
|
||||
printSettings.mediaSize = {
|
||||
options.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: height,
|
||||
@@ -294,7 +292,7 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
};
|
||||
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
|
||||
const mediaSize = PDFPageSizes[pageSize];
|
||||
printSettings.mediaSize = {
|
||||
options.mediaSize = {
|
||||
...mediaSize,
|
||||
imageable_area_left_microns: 0,
|
||||
imageable_area_bottom_microns: 0,
|
||||
@@ -307,9 +305,9 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
|
||||
|
||||
if (this._print) {
|
||||
if (callback) {
|
||||
this._print(printSettings, callback);
|
||||
this._print(options, callback);
|
||||
} else {
|
||||
this._print(printSettings);
|
||||
this._print(options);
|
||||
}
|
||||
} else {
|
||||
console.error('Error: Printing feature is disabled.');
|
||||
|
||||
@@ -144,3 +144,7 @@ feat_allow_code_cache_in_custom_schemes.patch
|
||||
enable_partition_alloc_ref_count_size.patch
|
||||
ensure_an_axcontext_before_painting.patch
|
||||
safely_crash_on_dangling_profile.patch
|
||||
prevent_mojotrap_event_re-ordering.patch
|
||||
m122_cherry_pick_cve-2024-25062_libxml_fix.patch
|
||||
allowlist_devtools_for_file_access_permission.patch
|
||||
update_crashpad_to_37afd37401253ebcebcf6e07ce15c8cfecb1a1cc.patch
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yang Guo <yangguo@chromium.org>
|
||||
Date: Tue, 19 Dec 2023 19:34:20 +0000
|
||||
Subject: Allowlist devtools:// for file access permission
|
||||
|
||||
Otherwise DevTools features which save logs to the filesystem are
|
||||
affected by content permissions, which contradicts developer
|
||||
expectations.
|
||||
|
||||
Fixed: 1483230
|
||||
Change-Id: Ia0848a9a192b2803a64f4104f4032219d6f3a885
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5132146
|
||||
Auto-Submit: Yang Guo <yangguo@chromium.org>
|
||||
Reviewed-by: Christian Dullweber <dullweber@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1239281}
|
||||
|
||||
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
index 38464529cc74e7b17373e1dd4f7bfd8cc68ff796..99323d6453749edd98f0cace905e9c5312620825 100644
|
||||
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
|
||||
@@ -2354,3 +2354,26 @@ TEST_F(HostContentSettingsMapTest, IncognitoInheritSaaAndRenew) {
|
||||
ContentSetting::CONTENT_SETTING_ALLOW);
|
||||
EXPECT_EQ(CONTENT_SETTING_ASK, otr_map->GetContentSetting(host, host, type));
|
||||
}
|
||||
+
|
||||
+// File access is not implemented on Android. Luckily we don't need it for DevTools.
|
||||
+#if !BUILDFLAG(IS_ANDROID)
|
||||
+TEST_F(HostContentSettingsMapTest, DevToolsFileAccess) {
|
||||
+ TestingProfile profile;
|
||||
+ HostContentSettingsMap* host_content_settings_map =
|
||||
+ HostContentSettingsMapFactory::GetForProfile(&profile);
|
||||
+
|
||||
+ GURL devtools_host("devtools://devtools/bundled/devtools_app.html");
|
||||
+ GURL example_host("https://example.com");
|
||||
+
|
||||
+ host_content_settings_map->SetDefaultContentSetting(
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, CONTENT_SETTING_BLOCK);
|
||||
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
|
||||
+ host_content_settings_map->GetContentSetting(
|
||||
+ devtools_host, devtools_host,
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD));
|
||||
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
|
||||
+ host_content_settings_map->GetContentSetting(
|
||||
+ example_host, example_host,
|
||||
+ ContentSettingsType::FILE_SYSTEM_WRITE_GUARD));
|
||||
+}
|
||||
+#endif // !BUILDFLAG(IS_ANDROID)
|
||||
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
|
||||
index 8021bd809315debd7171350187bbd684c23fd882..69c66a5e68f6a137875df19993a959000c56a2e6 100644
|
||||
--- a/components/content_settings/core/browser/content_settings_registry.cc
|
||||
+++ b/components/content_settings/core/browser/content_settings_registry.cc
|
||||
@@ -425,7 +425,8 @@ void ContentSettingsRegistry::Init() {
|
||||
|
||||
Register(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
|
||||
"file-system-write-guard", CONTENT_SETTING_ASK,
|
||||
- WebsiteSettingsInfo::UNSYNCABLE, /*allowlisted_schemes=*/{},
|
||||
+ WebsiteSettingsInfo::UNSYNCABLE,
|
||||
+ /*allowlisted_primary_schemes=*/{kChromeDevToolsScheme},
|
||||
/*valid_settings=*/
|
||||
{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK},
|
||||
WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE,
|
||||
@@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joey Arhar <jarhar@chromium.org>
|
||||
Date: Wed, 21 Feb 2024 21:06:46 +0000
|
||||
Subject: M122: cherry pick CVE-2024-25062 libxml fix
|
||||
|
||||
This patch cherry picks the CVE-2024-25062 fix from libxml:
|
||||
https://gitlab.gnome.org/GNOME/libxml2/-/commit/1a66b176055d25ee635bf328c7b35b381db0b71d
|
||||
|
||||
Bug: 325094430
|
||||
Change-Id: I526ee718269ed8700b90885630b67f00f2f95089
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5310037
|
||||
Auto-Submit: Joey Arhar <jarhar@chromium.org>
|
||||
Commit-Queue: David Baron <dbaron@chromium.org>
|
||||
Reviewed-by: David Baron <dbaron@chromium.org>
|
||||
Commit-Queue: Joey Arhar <jarhar@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#913}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/third_party/libxml/README.chromium b/third_party/libxml/README.chromium
|
||||
index 33cfec99e14c5090f6f9ac504689f2c2b482806c..a9a90fccb30f049e544923b5e4e28c67e63794f5 100644
|
||||
--- a/third_party/libxml/README.chromium
|
||||
+++ b/third_party/libxml/README.chromium
|
||||
@@ -36,5 +36,6 @@ Modifications:
|
||||
- LIBXML_XINCLUDE_ENABLED
|
||||
- LIBXML_XPTR_ENABLED
|
||||
- LIBXML_ZLIB_ENABLED
|
||||
+- Cherry picked fix for CVE-2024-25062
|
||||
|
||||
This import was generated by the chromium/roll.py script.
|
||||
diff --git a/third_party/libxml/src/xmlreader.c b/third_party/libxml/src/xmlreader.c
|
||||
index c04cb11311c2af03608f62b54f8d6ae58a6c1d93..9ce8a148b6806f39e5ce14e114bac1af767f5a50 100644
|
||||
--- a/third_party/libxml/src/xmlreader.c
|
||||
+++ b/third_party/libxml/src/xmlreader.c
|
||||
@@ -1378,6 +1378,7 @@ node_found:
|
||||
* Handle XInclude if asked for
|
||||
*/
|
||||
if ((reader->xinclude) && (reader->in_xinclude == 0) &&
|
||||
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
|
||||
(reader->node != NULL) &&
|
||||
(reader->node->type == XML_ELEMENT_NODE) &&
|
||||
(reader->node->ns != NULL) &&
|
||||
156
patches/chromium/prevent_mojotrap_event_re-ordering.patch
Normal file
156
patches/chromium/prevent_mojotrap_event_re-ordering.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Rockot <rockot@google.com>
|
||||
Date: Thu, 15 Feb 2024 20:30:22 +0000
|
||||
Subject: Prevent MojoTrap event re-ordering
|
||||
|
||||
(cherry picked from commit 3557a2fcbdd8167f97ca81171be2e0da9c4f0647)
|
||||
|
||||
Fixed: 1508753
|
||||
Change-Id: I9ec14a12e7d1d147bda63703e1d6619fa30c8a51
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5253039
|
||||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1254840}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5299857
|
||||
Reviewed-by: Oksana Zhuravlova <oksamyt@chromium.org>
|
||||
Commit-Queue: Alex Gough <ajgo@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#794}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/mojo/core/ipcz_driver/mojo_trap.cc b/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
index 7a5765a74a7f64e584b0a080e659c88c019adcbb..2c98335dd7846fe44fd048265078dfffcb0b63f6 100644
|
||||
--- a/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
+++ b/mojo/core/ipcz_driver/mojo_trap.cc
|
||||
@@ -544,7 +544,15 @@ void MojoTrap::DispatchOrQueueEvent(Trigger& trigger,
|
||||
}
|
||||
|
||||
dispatching_thread_ = base::PlatformThread::CurrentRef();
|
||||
- DispatchEvent(event);
|
||||
+
|
||||
+ // If `trigger.removed` is true, then either this is the cancellation event
|
||||
+ // for the trigger (in which case it's OK to dispatch), or it was cancelled on
|
||||
+ // some other thread while we were blocked above. In the latter case, this
|
||||
+ // event is no longer valid and cannot be dispatched.
|
||||
+ // See https://crbug.com/1508753.
|
||||
+ if (!trigger.removed || event.result == MOJO_RESULT_CANCELLED) {
|
||||
+ DispatchEvent(event);
|
||||
+ }
|
||||
|
||||
// NOTE: This vector is only shrunk by the clear() below, but it may
|
||||
// accumulate more events during each iteration. Hence we iterate by index.
|
||||
diff --git a/mojo/core/trap_unittest.cc b/mojo/core/trap_unittest.cc
|
||||
index 0fd449d9598810fd34372d69d1d1599a0c88b955..4058da72eef8b5a11432b9a17d6ff3ecfd1306e8 100644
|
||||
--- a/mojo/core/trap_unittest.cc
|
||||
+++ b/mojo/core/trap_unittest.cc
|
||||
@@ -1747,6 +1747,111 @@ TEST_F(TrapTest, TriggerDuringDestruction) {
|
||||
MojoClose(b);
|
||||
}
|
||||
|
||||
+TEST_F(TrapTest, RaceDispatchAndBlockedCancel) {
|
||||
+ // Regression test for https://crbug.com/1508753. This bug was caused by
|
||||
+ // reordering of a MOJO_RESULT_CANCELLED event to before some other event for
|
||||
+ // the same trap context, violating an API constraint that must be upheld for
|
||||
+ // memory safety in application code. The scenario which could elicit the bug
|
||||
+ // was as follows:
|
||||
+ //
|
||||
+ // 1. A single trap is watching two pipes, P and Q.
|
||||
+ // 2. Thread A closes pipe P, triggering a CANCELLED event.
|
||||
+ // 3. Thread A re-arms the trap from within the CANCELLED event handler.
|
||||
+ // 4. Thread B changes Q's state to elicit a event for Q (not CANCELLED).
|
||||
+ // 5. Thread B dispatch is blocked because thread A is still dispatching.
|
||||
+ // 6. Before thread B gets a chance to be scheduled, thread A closes Q.
|
||||
+ // 7. Thread A dispatches a CANCELLED event for Q.
|
||||
+ // 8. Thread B is scheduled and proceeds to dispatch its Q event. [BAD]
|
||||
+
|
||||
+ struct State;
|
||||
+
|
||||
+ struct Pipe {
|
||||
+ explicit Pipe(State* state) : state(state) { CreateMessagePipe(&a, &b); }
|
||||
+
|
||||
+ uintptr_t context() const { return reinterpret_cast<uintptr_t>(this); }
|
||||
+
|
||||
+ MojoHandle a;
|
||||
+ MojoHandle b;
|
||||
+ bool trigger_cancelled = false;
|
||||
+
|
||||
+ // Back-reference to common state so it's reachable from the event handler.
|
||||
+ const raw_ptr<State> state;
|
||||
+ };
|
||||
+
|
||||
+ struct State {
|
||||
+ Pipe pipe0{this};
|
||||
+ Pipe pipe1{this};
|
||||
+ MojoHandle trap;
|
||||
+ base::WaitableEvent event;
|
||||
+ };
|
||||
+ State state;
|
||||
+
|
||||
+ // NOTE: + to turn the lambda into a function pointer.
|
||||
+ const MojoTrapEventHandler event_handler = +[](const MojoTrapEvent* event) {
|
||||
+ auto& pipe = *reinterpret_cast<Pipe*>(event->trigger_context);
|
||||
+ auto& state = *pipe.state;
|
||||
+
|
||||
+ // If the bug is present, this expectation can fail flakily. No event should
|
||||
+ // fire for a pipe after its watch has been cancelled.
|
||||
+ EXPECT_FALSE(pipe.trigger_cancelled);
|
||||
+
|
||||
+ if (event->result == MOJO_RESULT_CANCELLED) {
|
||||
+ pipe.trigger_cancelled = true;
|
||||
+
|
||||
+ if (&pipe == &state.pipe0) {
|
||||
+ // When pipe0's watch is cancelled (on the main thread by closure down
|
||||
+ // below) we re-arm the trap immediately. This must succeed because
|
||||
+ // `pipe1.a` is now the only handle being watched, and it's still in an
|
||||
+ // uninteresting state.
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK,
|
||||
+ MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
|
||||
+
|
||||
+ // Unblock the other thread so it can elicit a trap event on pipe1 now
|
||||
+ // that the trap is re-armed. It will still block just before
|
||||
+ // dispatching as long as we're still in this event handler on the main
|
||||
+ // thread.
|
||||
+ state.event.Signal();
|
||||
+
|
||||
+ // A nice long delay to make it very likely for the waiting
|
||||
+ // ThreadedRunner to progress right up to its event dispatch.
|
||||
+ base::PlatformThread::Sleep(base::Milliseconds(10));
|
||||
+
|
||||
+ // Trigger cancellation for pipe1 by closing its `a`. This will queue a
|
||||
+ // CANCELLED event to fire on the same thread immediately after we
|
||||
+ // return from this handler.
|
||||
+ MojoClose(state.pipe1.a);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK,
|
||||
+ MojoCreateTrap(event_handler, nullptr, &state.trap));
|
||||
+ EXPECT_EQ(
|
||||
+ MOJO_RESULT_OK,
|
||||
+ MojoAddTrigger(state.trap, state.pipe0.a, MOJO_HANDLE_SIGNAL_READABLE,
|
||||
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
|
||||
+ state.pipe0.context(), nullptr));
|
||||
+ EXPECT_EQ(
|
||||
+ MOJO_RESULT_OK,
|
||||
+ MojoAddTrigger(state.trap, state.pipe1.a, MOJO_HANDLE_SIGNAL_READABLE,
|
||||
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
|
||||
+ state.pipe1.context(), nullptr));
|
||||
+ EXPECT_EQ(MOJO_RESULT_OK, MojoArmTrap(state.trap, nullptr, nullptr, nullptr));
|
||||
+
|
||||
+ ThreadedRunner close_pipe1_b(base::BindLambdaForTesting([&] {
|
||||
+ state.event.Wait();
|
||||
+ MojoClose(state.pipe1.b);
|
||||
+ }));
|
||||
+ close_pipe1_b.Start();
|
||||
+
|
||||
+ // Trigger cancellation of the watch on `pipe0.a`. See event_handler above.
|
||||
+ MojoClose(state.pipe0.a);
|
||||
+
|
||||
+ close_pipe1_b.Join();
|
||||
+ MojoClose(state.pipe0.b);
|
||||
+ MojoClose(state.trap);
|
||||
+}
|
||||
+
|
||||
base::RepeatingClosure g_do_random_thing_callback;
|
||||
|
||||
void ReadAllMessages(const MojoTrapEvent* event) {
|
||||
@@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Peraza <jperaza@chromium.org>
|
||||
Date: Tue, 5 Mar 2024 18:09:48 +0000
|
||||
Subject: Update Crashpad to 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
|
||||
|
||||
29ac83caeb94 [Fuchsia] remove use of fuchsia mac sdk
|
||||
37afd3740125 Properly update iterator
|
||||
|
||||
(cherry picked from commit 80b0e498bec1722e8cc310fe52698e7b690956f2)
|
||||
|
||||
Bug: 325296797
|
||||
Change-Id: I7eb39d1bccec802f1b043eebd20ec0e658fe0e04
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5311633
|
||||
Reviewed-by: Nico Weber <thakis@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1264232}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5335538
|
||||
Reviewed-by: Mark Mentovai <mark@chromium.org>
|
||||
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6261@{#1024}
|
||||
Cr-Branched-From: 9755d9d81e4a8cb5b4f76b23b761457479dbb06b-refs/heads/main@{#1250580}
|
||||
|
||||
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
|
||||
index e6eb8320371f0f367c131d1712cc0f4d1f410b77..3c3c141e10522d782cd13b5aaa32a640897323e7 100644
|
||||
--- a/third_party/crashpad/README.chromium
|
||||
+++ b/third_party/crashpad/README.chromium
|
||||
@@ -2,7 +2,7 @@ Name: Crashpad
|
||||
Short Name: crashpad
|
||||
URL: https://crashpad.chromium.org/
|
||||
Version: N/A
|
||||
-Revision: 4a93d7f4c407fee2168ea23195d0e30fbfc1f90c
|
||||
+Revision: 37afd37401253ebcebcf6e07ce15c8cfecb1a1cc
|
||||
License: Apache 2.0
|
||||
License File: crashpad/LICENSE
|
||||
Security Critical: yes
|
||||
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
|
||||
index 909ef7dce53d53486a21cd87e00dc63d3eb79b43..cea46fda079b0bd2aca4bfaeb53158d672cb2b31 100644
|
||||
--- a/third_party/crashpad/crashpad/DEPS
|
||||
+++ b/third_party/crashpad/crashpad/DEPS
|
||||
@@ -121,16 +121,6 @@ deps = {
|
||||
'0d6902558d92fe3d49ba9a8f638ddea829be595b',
|
||||
'condition': 'checkout_fuchsia',
|
||||
},
|
||||
- 'crashpad/third_party/fuchsia/sdk/mac-amd64': {
|
||||
- 'packages': [
|
||||
- {
|
||||
- 'package': 'fuchsia/sdk/core/mac-amd64',
|
||||
- 'version': 'latest'
|
||||
- },
|
||||
- ],
|
||||
- 'condition': 'checkout_fuchsia and host_os == "mac"',
|
||||
- 'dep_type': 'cipd'
|
||||
- },
|
||||
'crashpad/third_party/fuchsia/sdk/linux-amd64': {
|
||||
'packages': [
|
||||
{
|
||||
diff --git a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
index 0ad2ee97540174be07110f08e519b530aae045f5..c76722683ddf1ae1a562b3705d909a337a23621b 100644
|
||||
--- a/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
+++ b/third_party/crashpad/crashpad/snapshot/sanitized/module_snapshot_sanitized.cc
|
||||
@@ -99,9 +99,11 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
|
||||
std::map<std::string, std::string> annotations =
|
||||
snapshot_->AnnotationsSimpleMap();
|
||||
if (allowed_annotations_) {
|
||||
- for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) {
|
||||
- if (!KeyIsAllowed(kv->first, *allowed_annotations_)) {
|
||||
- annotations.erase(kv);
|
||||
+ for (auto kv = annotations.begin(); kv != annotations.end();) {
|
||||
+ if (KeyIsAllowed(kv->first, *allowed_annotations_)) {
|
||||
+ ++kv;
|
||||
+ } else {
|
||||
+ kv = annotations.erase(kv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,5 +53,6 @@ win_process_avoid_assert_after_spawning_store_app_4152.patch
|
||||
test_fix_edge_snapshot_stack_traces.patch
|
||||
chore_remove_use_of_deprecated_kmaxlength.patch
|
||||
fix_avx_detection.patch
|
||||
src_preload_function_for_environment.patch
|
||||
fix_undici_incorrectly_copies_headers_onto_fetches.patch
|
||||
module_rework_of_memory_management_in_vm_apis_with_the.patch
|
||||
src_preload_function_for_environment.patch
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +1,15 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cheng Zhao <zcbenz@gmail.com>
|
||||
Date: Mon, 22 Jan 2024 13:45:55 +0900
|
||||
Date: Mon, 4 Mar 2024 11:41:18 +0900
|
||||
Subject: src: preload function for Environment
|
||||
|
||||
https://github.com/nodejs/node/pull/51539
|
||||
|
||||
This PR adds a |preload| arg to the node::CreateEnvironment to allow
|
||||
embedders to set a preload function for the environment, which will run
|
||||
after the environment is loaded and before the main script runs.
|
||||
|
||||
This is similiar to the --require CLI option, but runs a C++ function,
|
||||
and can only be set by embedders.
|
||||
|
||||
The preload function can be used by embedders to inject scripts before
|
||||
running the main script, for example:
|
||||
1. In Electron it is used to initialize the ASAR virtual filesystem,
|
||||
inject custom process properties, etc.
|
||||
2. In VS Code it can be used to reset the module search paths for
|
||||
extensions.
|
||||
Backport https://github.com/nodejs/node/pull/51539
|
||||
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index fd5357997a4e05567146dc997e47af408e1fc8f4..cb53212069794eaac8ceaf28001f5db25e127f0a 100644
|
||||
index 2d892267a08772f4c37ee381c55f46b3a99f2232..e3daca3ba8cddac8db5fc73d78d869fedb4204af 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -127,6 +127,9 @@ function setupUserModules() {
|
||||
@@ -126,6 +126,9 @@ function setupUserModules() {
|
||||
initializeESMLoader();
|
||||
const CJSLoader = require('internal/modules/cjs/loader');
|
||||
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
|
||||
@@ -33,7 +19,7 @@ index fd5357997a4e05567146dc997e47af408e1fc8f4..cb53212069794eaac8ceaf28001f5db2
|
||||
loadPreloadModules();
|
||||
// Need to be done after --require setup.
|
||||
initializeFrozenIntrinsics();
|
||||
@@ -601,6 +604,10 @@ function initializeFrozenIntrinsics() {
|
||||
@@ -588,6 +591,10 @@ function initializeFrozenIntrinsics() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,120 +31,80 @@ index fd5357997a4e05567146dc997e47af408e1fc8f4..cb53212069794eaac8ceaf28001f5db2
|
||||
// For user code, we preload modules if `-r` is passed
|
||||
const preloadModules = getOptionValue('--require');
|
||||
diff --git a/src/api/environment.cc b/src/api/environment.cc
|
||||
index c4caef25af670658965fc740ce03c2d2c4ed3e66..19443a9672441da5b98921eab9385083a72e3b7e 100644
|
||||
index c4caef25af670658965fc740ce03c2d2c4ed3e66..465ff36b79c36d29777c7b1abe3a35d3be5de93e 100644
|
||||
--- a/src/api/environment.cc
|
||||
+++ b/src/api/environment.cc
|
||||
@@ -404,14 +404,16 @@ Environment* CreateEnvironment(
|
||||
const std::vector<std::string>& exec_args,
|
||||
EnvironmentFlags::Flags flags,
|
||||
ThreadId thread_id,
|
||||
- std::unique_ptr<InspectorParentHandle> inspector_parent_handle) {
|
||||
+ std::unique_ptr<InspectorParentHandle> inspector_parent_handle,
|
||||
+ EmbedderPreloadCallback preload) {
|
||||
Isolate* isolate = context->GetIsolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
Context::Scope context_scope(context);
|
||||
// TODO(addaleax): This is a much better place for parsing per-Environment
|
||||
// options than the global parse call.
|
||||
Environment* env = new Environment(
|
||||
- isolate_data, context, args, exec_args, nullptr, flags, thread_id);
|
||||
+ isolate_data, context, args, exec_args, nullptr, flags, thread_id,
|
||||
+ std::move(preload));
|
||||
@@ -484,18 +484,22 @@ NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_INSPECTOR
|
||||
if (env->should_create_inspector()) {
|
||||
-MaybeLocal<Value> LoadEnvironment(
|
||||
- Environment* env,
|
||||
- StartExecutionCallback cb) {
|
||||
+MaybeLocal<Value> LoadEnvironment(Environment* env,
|
||||
+ StartExecutionCallback cb,
|
||||
+ EmbedderPreloadCallback preload) {
|
||||
env->InitializeLibuv();
|
||||
env->InitializeDiagnostics();
|
||||
+ if (preload) {
|
||||
+ env->set_embedder_preload(std::move(preload));
|
||||
+ }
|
||||
|
||||
return StartExecution(env, cb);
|
||||
}
|
||||
|
||||
MaybeLocal<Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- const char* main_script_source_utf8) {
|
||||
+ const char* main_script_source_utf8,
|
||||
+ EmbedderPreloadCallback preload) {
|
||||
CHECK_NOT_NULL(main_script_source_utf8);
|
||||
return LoadEnvironment(
|
||||
env, [&](const StartExecutionCallbackInfo& info) -> MaybeLocal<Value> {
|
||||
@@ -508,7 +512,8 @@ MaybeLocal<Value> LoadEnvironment(
|
||||
std::vector<Local<Value>> args = {realm->process_object(),
|
||||
realm->builtin_module_require()};
|
||||
return realm->ExecuteBootstrapper(name.c_str(), &args);
|
||||
- });
|
||||
+ },
|
||||
+ std::move(preload));
|
||||
}
|
||||
|
||||
Environment* GetCurrentEnvironment(Local<Context> context) {
|
||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||
index 103dc6711e71e15da640edc5e017bc638ddc6ad1..4d12e6e406c1078fd92f3cc837c2f8a926fadd1d 100644
|
||||
index c68ea0fb1d45fadfa64f092a96ee04ecd9fe4c2d..2db4d431b3ce573e77e282b74c06a57a38d09417 100644
|
||||
--- a/src/env-inl.h
|
||||
+++ b/src/env-inl.h
|
||||
@@ -388,6 +388,10 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
|
||||
@@ -378,6 +378,14 @@ inline std::vector<double>* Environment::destroy_async_id_list() {
|
||||
return &destroy_async_id_list_;
|
||||
}
|
||||
|
||||
+inline const EmbedderPreloadCallback& Environment::embedder_preload() const {
|
||||
+ return embedder_preload_;
|
||||
+}
|
||||
+
|
||||
+inline void Environment::set_embedder_preload(EmbedderPreloadCallback fn) {
|
||||
+ embedder_preload_ = std::move(fn);
|
||||
+}
|
||||
+
|
||||
inline double Environment::new_async_id() {
|
||||
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
|
||||
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index 5bdbfad4f4d3ef16c41ff8e5dae90f48a6d5f5a2..98fd9bdcf99e7ddcd4ae6baa23998b855cc3ddfe 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -643,7 +643,8 @@ Environment::Environment(IsolateData* isolate_data,
|
||||
const std::vector<std::string>& exec_args,
|
||||
const EnvSerializeInfo* env_info,
|
||||
EnvironmentFlags::Flags flags,
|
||||
- ThreadId thread_id)
|
||||
+ ThreadId thread_id,
|
||||
+ EmbedderPreloadCallback preload)
|
||||
: isolate_(isolate),
|
||||
isolate_data_(isolate_data),
|
||||
async_hooks_(isolate, MAYBE_FIELD_PTR(env_info, async_hooks)),
|
||||
@@ -666,7 +667,8 @@ Environment::Environment(IsolateData* isolate_data,
|
||||
flags_(flags),
|
||||
thread_id_(thread_id.id == static_cast<uint64_t>(-1)
|
||||
? AllocateEnvironmentThreadId().id
|
||||
- : thread_id.id) {
|
||||
+ : thread_id.id),
|
||||
+ embedder_preload_(std::move(preload)) {
|
||||
// We'll be creating new objects so make sure we've entered the context.
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
@@ -736,14 +738,16 @@ Environment::Environment(IsolateData* isolate_data,
|
||||
const std::vector<std::string>& exec_args,
|
||||
const EnvSerializeInfo* env_info,
|
||||
EnvironmentFlags::Flags flags,
|
||||
- ThreadId thread_id)
|
||||
+ ThreadId thread_id,
|
||||
+ EmbedderPreloadCallback preload)
|
||||
: Environment(isolate_data,
|
||||
context->GetIsolate(),
|
||||
args,
|
||||
exec_args,
|
||||
env_info,
|
||||
flags,
|
||||
- thread_id) {
|
||||
+ thread_id,
|
||||
+ std::move(preload)) {
|
||||
InitializeMainContext(context, env_info);
|
||||
}
|
||||
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index 36e8e7d960a95a9040ad963c79a7f66c89233c87..1b11c4243d18f14f4aaaad2683295ffff49dfd04 100644
|
||||
index 9b5fcdaed5fdda44cd8103a0821a7b5358523f4e..6a5a7eeec866f6e501feeb03fe7da5ada011afa0 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -579,7 +579,8 @@ class Environment : public MemoryRetainer {
|
||||
const std::vector<std::string>& exec_args,
|
||||
const EnvSerializeInfo* env_info,
|
||||
EnvironmentFlags::Flags flags,
|
||||
- ThreadId thread_id);
|
||||
+ ThreadId thread_id,
|
||||
+ EmbedderPreloadCallback preload);
|
||||
void InitializeMainContext(v8::Local<v8::Context> context,
|
||||
const EnvSerializeInfo* env_info);
|
||||
// Create an Environment and initialize the provided principal context for it.
|
||||
@@ -589,7 +590,8 @@ class Environment : public MemoryRetainer {
|
||||
const std::vector<std::string>& exec_args,
|
||||
const EnvSerializeInfo* env_info,
|
||||
EnvironmentFlags::Flags flags,
|
||||
- ThreadId thread_id);
|
||||
+ ThreadId thread_id,
|
||||
+ EmbedderPreloadCallback preload);
|
||||
~Environment() override;
|
||||
|
||||
void InitializeLibuv();
|
||||
@@ -933,6 +935,8 @@ class Environment : public MemoryRetainer {
|
||||
@@ -925,6 +925,9 @@ class Environment : public MemoryRetainer {
|
||||
|
||||
#endif // HAVE_INSPECTOR
|
||||
|
||||
+ inline const EmbedderPreloadCallback& embedder_preload() const;
|
||||
+ inline void set_embedder_preload(EmbedderPreloadCallback fn);
|
||||
+
|
||||
inline void set_process_exit_handler(
|
||||
std::function<void(Environment*, int)>&& handler);
|
||||
|
||||
@@ -1102,6 +1106,7 @@ class Environment : public MemoryRetainer {
|
||||
@@ -1094,6 +1097,7 @@ class Environment : public MemoryRetainer {
|
||||
DefaultProcessExitHandler };
|
||||
|
||||
std::unique_ptr<Realm> principal_realm_ = nullptr;
|
||||
@@ -167,55 +113,45 @@ index 36e8e7d960a95a9040ad963c79a7f66c89233c87..1b11c4243d18f14f4aaaad2683295fff
|
||||
// Used by allocate_managed_buffer() and release_managed_buffer() to keep
|
||||
// track of the BackingStore for a given pointer.
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 26368061a909e6abc62a4cf261a5dbbd79404f1a..bb4065e33164c3ea762a27b71606ab4ed7b1b336 100644
|
||||
index 26368061a909e6abc62a4cf261a5dbbd79404f1a..0dec1e311d7c00c2b830a0b2a6bde4336aebe68b 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -593,9 +593,21 @@ struct InspectorParentHandle {
|
||||
virtual ~InspectorParentHandle();
|
||||
};
|
||||
@@ -630,13 +630,33 @@ struct StartExecutionCallbackInfo {
|
||||
|
||||
using StartExecutionCallback =
|
||||
std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
|
||||
+using EmbedderPreloadCallback =
|
||||
+ std::function<void(Environment* env,
|
||||
+ v8::Local<v8::Value> process,
|
||||
+ v8::Local<v8::Value> require)>;
|
||||
+
|
||||
// TODO(addaleax): Maybe move per-Environment options parsing here.
|
||||
// Returns nullptr when the Environment cannot be created e.g. there are
|
||||
// pending JavaScript exceptions.
|
||||
+//
|
||||
+// The |preload| function will run before executing the entry point, which
|
||||
+// is usually used by embedders to inject scripts. The function is executed
|
||||
+// with preload(process, require), and the passed require function has access
|
||||
+// to internal Node.js modules. The |preload| function is inherited by worker
|
||||
+// threads and thus will run in work threads, so make sure the function is
|
||||
+// thread-safe.
|
||||
NODE_EXTERN Environment* CreateEnvironment(
|
||||
IsolateData* isolate_data,
|
||||
v8::Local<v8::Context> context,
|
||||
@@ -603,7 +615,8 @@ NODE_EXTERN Environment* CreateEnvironment(
|
||||
const std::vector<std::string>& exec_args,
|
||||
EnvironmentFlags::Flags flags = EnvironmentFlags::kDefaultFlags,
|
||||
ThreadId thread_id = {} /* allocates a thread id automatically */,
|
||||
- std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {});
|
||||
+ std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {},
|
||||
+ EmbedderPreloadCallback preload = nullptr);
|
||||
|
||||
// Returns a handle that can be passed to `LoadEnvironment()`, making the
|
||||
// child Environment accessible to the inspector as if it were a Node.js Worker.
|
||||
diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc
|
||||
index a8661c3c2263fc62e55659310b8da12fc414361e..849442aa8c923808420cbc888befea7d3f1f4c1b 100644
|
||||
--- a/src/node_main_instance.cc
|
||||
+++ b/src/node_main_instance.cc
|
||||
@@ -157,7 +157,8 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code) {
|
||||
exec_args_,
|
||||
&(snapshot_data_->env_info),
|
||||
EnvironmentFlags::kDefaultFlags,
|
||||
- {}));
|
||||
+ {},
|
||||
+ nullptr));
|
||||
context = Context::FromSnapshot(isolate_,
|
||||
SnapshotData::kNodeMainContextIndex,
|
||||
{DeserializeNodeInternalFields, env.get()})
|
||||
+// Run initialization for the environment.
|
||||
+//
|
||||
+// The |preload| function, usually used by embedders to inject scripts,
|
||||
+// will be run by Node.js before Node.js executes the entry point.
|
||||
+// The function is guaranteed to run before the user land module loader running
|
||||
+// any user code, so it is safe to assume that at this point, no user code has
|
||||
+// been run yet.
|
||||
+// The function will be executed with preload(process, require), and the passed
|
||||
+// require function has access to internal Node.js modules. There is no
|
||||
+// stability guarantee about the internals exposed to the internal require
|
||||
+// function. Expect breakages when updating Node.js versions if the embedder
|
||||
+// imports internal modules with the internal require function.
|
||||
+// Worker threads created in the environment will also respect The |preload|
|
||||
+// function, so make sure the function is thread-safe.
|
||||
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- StartExecutionCallback cb);
|
||||
+ StartExecutionCallback cb,
|
||||
+ EmbedderPreloadCallback preload = nullptr);
|
||||
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
|
||||
Environment* env,
|
||||
- const char* main_script_source_utf8);
|
||||
+ const char* main_script_source_utf8,
|
||||
+ EmbedderPreloadCallback preload = nullptr);
|
||||
NODE_EXTERN void FreeEnvironment(Environment* env);
|
||||
|
||||
// Set a callback that is called when process.exit() is called from JS,
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index 365748f046f9d0f232d4f0ebc7b0c7f56bbd74e2..a076de0c5e577114a6166844ab3b4f02db8065ad 100644
|
||||
--- a/src/node_options.cc
|
||||
@@ -234,24 +170,28 @@ index 365748f046f9d0f232d4f0ebc7b0c7f56bbd74e2..a076de0c5e577114a6166844ab3b4f02
|
||||
}
|
||||
|
||||
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc
|
||||
index f70e6ddf4303f303d7ace859b257738fd6707853..e6eb9d8602193ee8823724061592ae2ac681a816 100644
|
||||
index f70e6ddf4303f303d7ace859b257738fd6707853..3f89973349f03128ab77f7cf3902506ec79d1272 100644
|
||||
--- a/src/node_snapshotable.cc
|
||||
+++ b/src/node_snapshotable.cc
|
||||
@@ -1462,6 +1462,13 @@ void SerializeSnapshotableObjects(Realm* realm,
|
||||
@@ -1462,6 +1462,17 @@ void SerializeSnapshotableObjects(Realm* realm,
|
||||
|
||||
namespace mksnapshot {
|
||||
|
||||
+static void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
|
||||
+void RunEmbedderPreload(const FunctionCallbackInfo<Value>& args) {
|
||||
+ Environment* env = Environment::GetCurrent(args);
|
||||
+ CHECK(env->embedder_preload());
|
||||
+ CHECK_EQ(args.Length(), 2);
|
||||
+ env->embedder_preload()(env, args[0], args[1]);
|
||||
+ Local<Value> process_obj = args[0];
|
||||
+ Local<Value> require_fn = args[1];
|
||||
+ CHECK(process_obj->IsObject());
|
||||
+ CHECK(require_fn->IsFunction());
|
||||
+ env->embedder_preload()(env, process_obj, require_fn);
|
||||
+}
|
||||
+
|
||||
void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
|
||||
CHECK(args[0]->IsString());
|
||||
Local<String> filename = args[0].As<String>();
|
||||
@@ -1515,6 +1522,7 @@ void Initialize(Local<Object> target,
|
||||
@@ -1515,6 +1526,7 @@ void Initialize(Local<Object> target,
|
||||
Local<Value> unused,
|
||||
Local<Context> context,
|
||||
void* priv) {
|
||||
@@ -259,7 +199,7 @@ index f70e6ddf4303f303d7ace859b257738fd6707853..e6eb9d8602193ee8823724061592ae2a
|
||||
SetMethod(context, target, "compileSerializeMain", CompileSerializeMain);
|
||||
SetMethod(context, target, "setSerializeCallback", SetSerializeCallback);
|
||||
SetMethod(context, target, "setDeserializeCallback", SetDeserializeCallback);
|
||||
@@ -1525,6 +1533,7 @@ void Initialize(Local<Object> target,
|
||||
@@ -1525,6 +1537,7 @@ void Initialize(Local<Object> target,
|
||||
}
|
||||
|
||||
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
@@ -268,7 +208,7 @@ index f70e6ddf4303f303d7ace859b257738fd6707853..e6eb9d8602193ee8823724061592ae2a
|
||||
registry->Register(SetSerializeCallback);
|
||||
registry->Register(SetDeserializeCallback);
|
||||
diff --git a/src/node_worker.cc b/src/node_worker.cc
|
||||
index 6a49144ec4f2059fe75983609b0768e4c2b1817d..dc2eb247b011f9cb1945c173c49e029f068ef103 100644
|
||||
index 6a49144ec4f2059fe75983609b0768e4c2b1817d..13b0445370c70cf3765a4af44336c16ac2e1035d 100644
|
||||
--- a/src/node_worker.cc
|
||||
+++ b/src/node_worker.cc
|
||||
@@ -60,6 +60,7 @@ Worker::Worker(Environment* env,
|
||||
@@ -279,16 +219,20 @@ index 6a49144ec4f2059fe75983609b0768e4c2b1817d..dc2eb247b011f9cb1945c173c49e029f
|
||||
snapshot_data_(snapshot_data) {
|
||||
Debug(this, "Creating new worker instance with thread id %llu",
|
||||
thread_id_.id);
|
||||
@@ -333,7 +334,8 @@ void Worker::Run() {
|
||||
std::move(exec_argv_),
|
||||
static_cast<EnvironmentFlags::Flags>(environment_flags_),
|
||||
thread_id_,
|
||||
- std::move(inspector_parent_handle_)));
|
||||
+ std::move(inspector_parent_handle_),
|
||||
+ std::move(embedder_preload_)));
|
||||
if (is_stopped()) return;
|
||||
CHECK_NOT_NULL(env_);
|
||||
env_->set_env_vars(std::move(env_vars_));
|
||||
@@ -354,8 +355,12 @@ void Worker::Run() {
|
||||
}
|
||||
|
||||
Debug(this, "Created message port for worker %llu", thread_id_.id);
|
||||
- if (LoadEnvironment(env_.get(), StartExecutionCallback{}).IsEmpty())
|
||||
+ if (LoadEnvironment(env_.get(),
|
||||
+ StartExecutionCallback{},
|
||||
+ std::move(embedder_preload_))
|
||||
+ .IsEmpty()) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
Debug(this, "Loaded environment for worker %llu", thread_id_.id);
|
||||
}
|
||||
diff --git a/src/node_worker.h b/src/node_worker.h
|
||||
index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9c515e473 100644
|
||||
--- a/src/node_worker.h
|
||||
@@ -302,7 +246,7 @@ index a77c416735a79feb3f54e40d72a98c8903a20ccd..deab68576f6330f8bcfb4703fd05dbb9
|
||||
// A raw flag that is used by creator and worker threads to
|
||||
// sync up on pre-mature termination of worker - while in the
|
||||
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc
|
||||
index 09dcb1dccc1b28048c6300e2c23c2c40722272af..14a76a9baa7ca39a628553f730cde6c3c04c6be9 100644
|
||||
index 09dcb1dccc1b28048c6300e2c23c2c40722272af..54460cd9ecf3c8bbf9927598fcbaf05f5937cf9a 100644
|
||||
--- a/test/cctest/test_environment.cc
|
||||
+++ b/test/cctest/test_environment.cc
|
||||
@@ -740,3 +740,31 @@ TEST_F(EnvironmentTest, RequestInterruptAtExit) {
|
||||
@@ -320,20 +264,20 @@ index 09dcb1dccc1b28048c6300e2c23c2c40722272af..14a76a9baa7ca39a628553f730cde6c3
|
||||
+ v8::Local<v8::Value> require) {
|
||||
+ CHECK(process->IsObject());
|
||||
+ CHECK(require->IsFunction());
|
||||
+ process.As<v8::Object>()->Set(
|
||||
+ env->context(),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "prop"),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "preload")).Check();
|
||||
+ process.As<v8::Object>()
|
||||
+ ->Set(env->context(),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "prop"),
|
||||
+ v8::String::NewFromUtf8Literal(env->isolate(), "preload"))
|
||||
+ .Check();
|
||||
+ };
|
||||
+
|
||||
+ std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)> env(
|
||||
+ node::CreateEnvironment(isolate_data_, context, {}, {},
|
||||
+ node::EnvironmentFlags::kDefaultFlags, {}, {},
|
||||
+ preload),
|
||||
+ node::CreateEnvironment(isolate_data_, context, {}, {}),
|
||||
+ node::FreeEnvironment);
|
||||
+
|
||||
+ v8::Local<v8::Value> main_ret =
|
||||
+ node::LoadEnvironment(env.get(), "return process.prop;").ToLocalChecked();
|
||||
+ node::LoadEnvironment(env.get(), "return process.prop;", preload)
|
||||
+ .ToLocalChecked();
|
||||
+ node::Utf8Value main_ret_str(isolate_, main_ret);
|
||||
+ EXPECT_EQ(std::string(*main_ret_str), "preload");
|
||||
+}
|
||||
|
||||
@@ -2,3 +2,5 @@ build_gn.patch
|
||||
do_not_export_private_v8_symbols_on_windows.patch
|
||||
fix_build_deprecated_attribute_for_older_msvc_versions.patch
|
||||
chore_allow_customizing_microtask_policy_per_context.patch
|
||||
merged_wasm_add_bounds_check_in_tier-up_of_wasm-to-js_wrapper.patch
|
||||
merged_parser_fix_home_object_proxy_to_work_off-thread.patch
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shu-yu Guo <syg@chromium.org>
|
||||
Date: Thu, 7 Mar 2024 14:55:28 -0800
|
||||
Subject: Merged: [parser] Fix home object proxy to work off-thread
|
||||
|
||||
Because the home object has special scope lookup rules due to class
|
||||
heritage position, VariableProxies of the home object are currently
|
||||
directly created on the correct scope during parsing. However, during
|
||||
off-thread parsing the main thread is parked, and the correct scope
|
||||
may try to dereference a main-thread Handle.
|
||||
|
||||
This CL moves the logic into ResolveVariable instead, which happens
|
||||
during postprocessing, with the main thread unparked.
|
||||
|
||||
Fixed: chromium:327740539
|
||||
|
||||
(cherry picked from commit 8f477f936c9b9e6b4c9f35a8ccc5e65bd4cb7f4e)
|
||||
|
||||
Change-Id: I16805ad35f5d70d1acadaf1f5440dfc159dbfa6c
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5363634
|
||||
Reviewed-by: Deepti Gandluri <gdeepti@chromium.org>
|
||||
Commit-Queue: Shu-yu Guo <syg@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#44}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/ast/ast.h b/src/ast/ast.h
|
||||
index cf9d52eeed67a3d7685916987b540950385f98ce..7bb30723607ec9a3cef9d45b032c3edfa55bdc9c 100644
|
||||
--- a/src/ast/ast.h
|
||||
+++ b/src/ast/ast.h
|
||||
@@ -1534,6 +1534,12 @@ class VariableProxy final : public Expression {
|
||||
bit_field_ = IsRemovedFromUnresolvedField::update(bit_field_, true);
|
||||
}
|
||||
|
||||
+ bool is_home_object() const { return IsHomeObjectField::decode(bit_field_); }
|
||||
+
|
||||
+ void set_is_home_object() {
|
||||
+ bit_field_ = IsHomeObjectField::update(bit_field_, true);
|
||||
+ }
|
||||
+
|
||||
// Provides filtered access to the unresolved variable proxy threaded list.
|
||||
struct UnresolvedNext {
|
||||
static VariableProxy** filter(VariableProxy** t) {
|
||||
@@ -1565,6 +1571,7 @@ class VariableProxy final : public Expression {
|
||||
bit_field_ |= IsAssignedField::encode(false) |
|
||||
IsResolvedField::encode(false) |
|
||||
IsRemovedFromUnresolvedField::encode(false) |
|
||||
+ IsHomeObjectField::encode(false) |
|
||||
HoleCheckModeField::encode(HoleCheckMode::kElided);
|
||||
}
|
||||
|
||||
@@ -1574,7 +1581,8 @@ class VariableProxy final : public Expression {
|
||||
using IsResolvedField = IsAssignedField::Next<bool, 1>;
|
||||
using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
|
||||
using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
|
||||
- using HoleCheckModeField = IsNewTargetField::Next<HoleCheckMode, 1>;
|
||||
+ using IsHomeObjectField = IsNewTargetField::Next<bool, 1>;
|
||||
+ using HoleCheckModeField = IsHomeObjectField::Next<HoleCheckMode, 1>;
|
||||
|
||||
union {
|
||||
const AstRawString* raw_name_; // if !is_resolved_
|
||||
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
||||
index 672440a2b4b9ad6262c49be50d03377b413452a6..6dfcd45cf208e58a2fc0cd18ba3b115bae35a0d5 100644
|
||||
--- a/src/ast/scopes.cc
|
||||
+++ b/src/ast/scopes.cc
|
||||
@@ -491,7 +491,6 @@ Scope* Scope::DeserializeScopeChain(IsolateT* isolate, Zone* zone,
|
||||
if (cache_scope_found) {
|
||||
outer_scope->set_deserialized_scope_uses_external_cache();
|
||||
} else {
|
||||
- DCHECK(!cache_scope_found);
|
||||
cache_scope_found =
|
||||
outer_scope->is_declaration_scope() && !outer_scope->is_eval_scope();
|
||||
}
|
||||
@@ -970,9 +969,14 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
|
||||
DCHECK(!cache->deserialized_scope_uses_external_cache());
|
||||
// The case where where the cache can be another scope is when the cache scope
|
||||
// is the last scope that doesn't use an external cache.
|
||||
+ //
|
||||
+ // The one exception to this is when looking up the home object, which may
|
||||
+ // skip multiple scopes that don't use an external cache (e.g., several arrow
|
||||
+ // functions).
|
||||
DCHECK_IMPLIES(
|
||||
cache != this,
|
||||
- cache->outer_scope()->deserialized_scope_uses_external_cache());
|
||||
+ cache->outer_scope()->deserialized_scope_uses_external_cache() ||
|
||||
+ cache->GetHomeObjectScope() == this);
|
||||
DCHECK_NULL(cache->variables_.Lookup(name));
|
||||
DisallowGarbageCollection no_gc;
|
||||
|
||||
@@ -2282,7 +2286,33 @@ Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
|
||||
|
||||
void Scope::ResolveVariable(VariableProxy* proxy) {
|
||||
DCHECK(!proxy->is_resolved());
|
||||
- Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
|
||||
+ Variable* var;
|
||||
+ if (V8_UNLIKELY(proxy->is_home_object())) {
|
||||
+ // VariableProxies of the home object cannot be resolved like a normal
|
||||
+ // variable. Consider the case of a super.property usage in heritage
|
||||
+ // position:
|
||||
+ //
|
||||
+ // class C extends super.foo { m() { super.bar(); } }
|
||||
+ //
|
||||
+ // The super.foo property access is logically nested under C's class scope,
|
||||
+ // which also has a home object due to its own method m's usage of
|
||||
+ // super.bar(). However, super.foo must resolve super in C's outer scope.
|
||||
+ //
|
||||
+ // Because of the above, start resolving home objects directly at the home
|
||||
+ // object scope instead of the current scope.
|
||||
+ Scope* scope = GetDeclarationScope()->GetHomeObjectScope();
|
||||
+ DCHECK_NOT_NULL(scope);
|
||||
+ if (scope->scope_info_.is_null()) {
|
||||
+ var = Lookup<kParsedScope>(proxy, scope, nullptr);
|
||||
+ } else {
|
||||
+ Scope* entry_cache = scope->deserialized_scope_uses_external_cache()
|
||||
+ ? GetNonEvalDeclarationScope()
|
||||
+ : scope;
|
||||
+ var = Lookup<kDeserializedScope>(proxy, scope, nullptr, entry_cache);
|
||||
+ }
|
||||
+ } else {
|
||||
+ var = Lookup<kParsedScope>(proxy, this, nullptr);
|
||||
+ }
|
||||
DCHECK_NOT_NULL(var);
|
||||
ResolveTo(proxy, var);
|
||||
}
|
||||
@@ -2752,48 +2782,6 @@ int Scope::ContextLocalCount() const {
|
||||
(is_function_var_in_context ? 1 : 0);
|
||||
}
|
||||
|
||||
-VariableProxy* Scope::NewHomeObjectVariableProxy(AstNodeFactory* factory,
|
||||
- const AstRawString* name,
|
||||
- int start_pos) {
|
||||
- // VariableProxies of the home object cannot be resolved like a normal
|
||||
- // variable. Consider the case of a super.property usage in heritage position:
|
||||
- //
|
||||
- // class C extends super.foo { m() { super.bar(); } }
|
||||
- //
|
||||
- // The super.foo property access is logically nested under C's class scope,
|
||||
- // which also has a home object due to its own method m's usage of
|
||||
- // super.bar(). However, super.foo must resolve super in C's outer scope.
|
||||
- //
|
||||
- // Because of the above, home object VariableProxies are always made directly
|
||||
- // on the Scope that needs the home object instead of the innermost scope.
|
||||
- DCHECK(needs_home_object());
|
||||
- if (!scope_info_.is_null()) {
|
||||
- // This is a lazy compile, so the home object's context slot is already
|
||||
- // known.
|
||||
- Variable* home_object = variables_.Lookup(name);
|
||||
- if (home_object == nullptr) {
|
||||
- VariableLookupResult lookup_result;
|
||||
- int index = scope_info_->ContextSlotIndex(name->string(), &lookup_result);
|
||||
- DCHECK_GE(index, 0);
|
||||
- bool was_added;
|
||||
- home_object = variables_.Declare(zone(), this, name, lookup_result.mode,
|
||||
- NORMAL_VARIABLE, lookup_result.init_flag,
|
||||
- lookup_result.maybe_assigned_flag,
|
||||
- IsStaticFlag::kNotStatic, &was_added);
|
||||
- DCHECK(was_added);
|
||||
- home_object->AllocateTo(VariableLocation::CONTEXT, index);
|
||||
- }
|
||||
- return factory->NewVariableProxy(home_object, start_pos);
|
||||
- }
|
||||
- // This is not a lazy compile. Add the unresolved home object VariableProxy to
|
||||
- // the unresolved list of the home object scope, which is not necessarily the
|
||||
- // innermost scope.
|
||||
- VariableProxy* proxy =
|
||||
- factory->NewVariableProxy(name, NORMAL_VARIABLE, start_pos);
|
||||
- AddUnresolved(proxy);
|
||||
- return proxy;
|
||||
-}
|
||||
-
|
||||
bool IsComplementaryAccessorPair(VariableMode a, VariableMode b) {
|
||||
switch (a) {
|
||||
case VariableMode::kPrivateGetterOnly:
|
||||
diff --git a/src/ast/scopes.h b/src/ast/scopes.h
|
||||
index b4c2e8b2136813985231a722c6dbcd26e2c17336..751aaee3d11ecc0da71e2171dd42ed4b85d00219 100644
|
||||
--- a/src/ast/scopes.h
|
||||
+++ b/src/ast/scopes.h
|
||||
@@ -603,10 +603,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
||||
needs_home_object_ = true;
|
||||
}
|
||||
|
||||
- VariableProxy* NewHomeObjectVariableProxy(AstNodeFactory* factory,
|
||||
- const AstRawString* name,
|
||||
- int start_pos);
|
||||
-
|
||||
bool RemoveInnerScope(Scope* inner_scope) {
|
||||
DCHECK_NOT_NULL(inner_scope);
|
||||
if (inner_scope == inner_scope_) {
|
||||
@@ -865,7 +861,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
FunctionKind function_kind() const { return function_kind_; }
|
||||
|
||||
// Inform the scope that the corresponding code uses "super".
|
||||
- Scope* RecordSuperPropertyUsage() {
|
||||
+ void RecordSuperPropertyUsage() {
|
||||
DCHECK(IsConciseMethod(function_kind()) ||
|
||||
IsAccessorFunction(function_kind()) ||
|
||||
IsClassConstructor(function_kind()));
|
||||
@@ -873,7 +869,6 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
|
||||
Scope* home_object_scope = GetHomeObjectScope();
|
||||
DCHECK_NOT_NULL(home_object_scope);
|
||||
home_object_scope->set_needs_home_object();
|
||||
- return home_object_scope;
|
||||
}
|
||||
|
||||
bool uses_super_property() const { return uses_super_property_; }
|
||||
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
||||
index af7add9aa8231233dffd5f04ca491b3f614c3f97..232a6bdae48d5d6300b53bfd05b42841d2eae664 100644
|
||||
--- a/src/parsing/parser-base.h
|
||||
+++ b/src/parsing/parser-base.h
|
||||
@@ -3823,9 +3823,9 @@ ParserBase<Impl>::ParseSuperExpression() {
|
||||
impl()->ReportMessage(MessageTemplate::kOptionalChainingNoSuper);
|
||||
return impl()->FailureExpression();
|
||||
}
|
||||
- Scope* home_object_scope = scope->RecordSuperPropertyUsage();
|
||||
+ scope->RecordSuperPropertyUsage();
|
||||
UseThis();
|
||||
- return impl()->NewSuperPropertyReference(home_object_scope, pos);
|
||||
+ return impl()->NewSuperPropertyReference(pos);
|
||||
}
|
||||
// super() is only allowed in derived constructor. new super() is never
|
||||
// allowed; it's reported as an error by
|
||||
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
||||
index d42cd361d230de2b7da93a05785b2b721ff372cd..4c1ce5360f2b7f8a9c8a19fcee25e65b3a433db5 100644
|
||||
--- a/src/parsing/parser.cc
|
||||
+++ b/src/parsing/parser.cc
|
||||
@@ -300,18 +300,17 @@ Expression* Parser::NewThrowError(Runtime::FunctionId id,
|
||||
return factory()->NewThrow(call_constructor, pos);
|
||||
}
|
||||
|
||||
-Expression* Parser::NewSuperPropertyReference(Scope* home_object_scope,
|
||||
- int pos) {
|
||||
+Expression* Parser::NewSuperPropertyReference(int pos) {
|
||||
const AstRawString* home_object_name;
|
||||
if (IsStatic(scope()->GetReceiverScope()->function_kind())) {
|
||||
home_object_name = ast_value_factory_->dot_static_home_object_string();
|
||||
} else {
|
||||
home_object_name = ast_value_factory_->dot_home_object_string();
|
||||
}
|
||||
- return factory()->NewSuperPropertyReference(
|
||||
- home_object_scope->NewHomeObjectVariableProxy(factory(), home_object_name,
|
||||
- pos),
|
||||
- pos);
|
||||
+
|
||||
+ VariableProxy* proxy = NewUnresolved(home_object_name, pos);
|
||||
+ proxy->set_is_home_object();
|
||||
+ return factory()->NewSuperPropertyReference(proxy, pos);
|
||||
}
|
||||
|
||||
Expression* Parser::NewSuperCallReference(int pos) {
|
||||
diff --git a/src/parsing/parser.h b/src/parsing/parser.h
|
||||
index 8aede5d6a2cd38b2ad02fa2d7542ea8163c29aa9..0e92f0350b5989781bda0eeb9746cfa18cd5e179 100644
|
||||
--- a/src/parsing/parser.h
|
||||
+++ b/src/parsing/parser.h
|
||||
@@ -798,7 +798,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
return factory()->NewThisExpression(pos);
|
||||
}
|
||||
|
||||
- Expression* NewSuperPropertyReference(Scope* home_object_scope, int pos);
|
||||
+ Expression* NewSuperPropertyReference(int pos);
|
||||
Expression* NewSuperCallReference(int pos);
|
||||
Expression* NewTargetExpression(int pos);
|
||||
Expression* ImportMetaExpression(int pos);
|
||||
diff --git a/src/parsing/preparser.h b/src/parsing/preparser.h
|
||||
index 6c4996bd06be782bd0f767a2bfb6d413cfc1ae82..2ca6b9ac407b0862d82be466eec624280b241b09 100644
|
||||
--- a/src/parsing/preparser.h
|
||||
+++ b/src/parsing/preparser.h
|
||||
@@ -1536,8 +1536,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
return PreParserExpression::This();
|
||||
}
|
||||
|
||||
- V8_INLINE PreParserExpression
|
||||
- NewSuperPropertyReference(Scope* home_object_scope, int pos) {
|
||||
+ V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
|
||||
return PreParserExpression::Default();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Haas <ahaas@chromium.org>
|
||||
Date: Tue, 20 Feb 2024 16:27:22 +0100
|
||||
Subject: Merged: [wasm] Add bounds check in tier-up of wasm-to-js wrapper
|
||||
|
||||
The entry index in the WasmApiFunctionRef was used to look for the given
|
||||
WasmApiFunctionRef in the indirect function tables, but it was not
|
||||
considered that the indirect function tables can have different lengths.
|
||||
|
||||
R=clemensb@chromium.org
|
||||
|
||||
Bug: 325893559
|
||||
|
||||
(cherry picked from commit 7330f46163e8a2c10a3d40ecbf554656f0ac55e8)
|
||||
|
||||
Change-Id: I52355890e21490c75566216985680c64e0b0db75
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5323850
|
||||
Commit-Queue: Andreas Haas <ahaas@chromium.org>
|
||||
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/12.2@{#38}
|
||||
Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1}
|
||||
Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934}
|
||||
|
||||
diff --git a/src/runtime/runtime-wasm.cc b/src/runtime/runtime-wasm.cc
|
||||
index 5f711bc606633bd916356f0eca5799ce63760dbd..1077e6bb3ec359ef540987d030e244f1789aa14d 100644
|
||||
--- a/src/runtime/runtime-wasm.cc
|
||||
+++ b/src/runtime/runtime-wasm.cc
|
||||
@@ -602,7 +602,8 @@ RUNTIME_FUNCTION(Runtime_TierUpWasmToJSWrapper) {
|
||||
for (int table_index = 0; table_index < table_count; ++table_index) {
|
||||
Handle<WasmIndirectFunctionTable> table =
|
||||
instance->GetIndirectFunctionTable(isolate, table_index);
|
||||
- if (table->refs()->get(entry_index) == *ref) {
|
||||
+ if (entry_index < table->refs()->length() &&
|
||||
+ table->refs()->get(entry_index) == *ref) {
|
||||
table->targets()
|
||||
->set<ExternalPointerTag::kWasmIndirectFunctionTargetTag>(
|
||||
entry_index, isolate, wasm_code->instruction_start());
|
||||
@@ -15,7 +15,10 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from .patches import PATCH_FILENAME_PREFIX, is_patch_location_line
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.append(SCRIPT_DIR)
|
||||
|
||||
from patches import PATCH_FILENAME_PREFIX, is_patch_location_line
|
||||
|
||||
UPSTREAM_HEAD='refs/patches/upstream-head'
|
||||
|
||||
|
||||
@@ -27,7 +27,9 @@ const getHeaders = (filePath: string, fileName: string) => {
|
||||
if (!extension) {
|
||||
throw new Error(`Failed to get headers for extensionless file: ${fileName}`);
|
||||
}
|
||||
console.log(`About to get size of ${filePath}`);
|
||||
const size = fs.statSync(filePath).size;
|
||||
console.log(`Got size of ${filePath}: ${size}`);
|
||||
const options: Record<string, string> = {
|
||||
json: 'text/json',
|
||||
zip: 'application/zip',
|
||||
@@ -46,10 +48,13 @@ const uploadUrl = `https://uploads.github.com/repos/electron/${targetRepo}/relea
|
||||
let retry = 0;
|
||||
|
||||
function uploadToGitHub () {
|
||||
console.log(`in uploadToGitHub for ${filePath}, ${fileName}`);
|
||||
const fileData = fs.createReadStream(filePath);
|
||||
console.log(`in uploadToGitHub, created readstream for ${filePath}`);
|
||||
octokit.repos.uploadReleaseAsset({
|
||||
url: uploadUrl,
|
||||
headers: getHeaders(filePath, fileName),
|
||||
data: fs.createReadStream(filePath) as any,
|
||||
data: fileData as any,
|
||||
name: fileName,
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
|
||||
@@ -363,10 +363,13 @@ def upload_io_to_github(release, filename, filepath, version):
|
||||
(filename))
|
||||
script_path = os.path.join(
|
||||
ELECTRON_DIR, 'script', 'release', 'uploaders', 'upload-to-github.ts')
|
||||
upload_gh_output = execute([TS_NODE, script_path, filepath, filename,
|
||||
str(release['id']), version])
|
||||
upload_process = subprocess.Popen([TS_NODE, script_path, filepath, filename,
|
||||
str(release['id']), version], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
if is_verbose_mode():
|
||||
print(upload_gh_output)
|
||||
for c in iter(lambda: upload_process.stdout.read(1), b""):
|
||||
sys.stdout.buffer.write(c)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def upload_sha256_checksum(version, file_path, key_prefix=None):
|
||||
|
||||
@@ -259,8 +259,7 @@ int NodeMain(int argc, char* argv[]) {
|
||||
env = node::CreateEnvironment(
|
||||
isolate_data, isolate->GetCurrentContext(), result->args(),
|
||||
result->exec_args(),
|
||||
static_cast<node::EnvironmentFlags::Flags>(env_flags), {}, {},
|
||||
&OnNodePreload);
|
||||
static_cast<node::EnvironmentFlags::Flags>(env_flags));
|
||||
CHECK_NE(nullptr, env);
|
||||
|
||||
node::SetIsolateUpForNode(isolate);
|
||||
@@ -285,7 +284,7 @@ int NodeMain(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
v8::HandleScope scope(isolate);
|
||||
node::LoadEnvironment(env, node::StartExecutionCallback{});
|
||||
node::LoadEnvironment(env, node::StartExecutionCallback{}, &OnNodePreload);
|
||||
|
||||
// Potential reasons we get Nothing here may include: the env
|
||||
// is stopping, or the user hooks process.emit('exit').
|
||||
|
||||
@@ -162,6 +162,10 @@ v8::Local<v8::Promise> DataPipeHolder::ReadAll(v8::Isolate* isolate) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
const char* DataPipeHolder::GetTypeName() {
|
||||
return "DataPipeHolder";
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<DataPipeHolder> DataPipeHolder::Create(
|
||||
v8::Isolate* isolate,
|
||||
|
||||
@@ -18,7 +18,9 @@ namespace electron::api {
|
||||
// Retains reference to the data pipe.
|
||||
class DataPipeHolder : public gin::Wrappable<DataPipeHolder> {
|
||||
public:
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
static gin::Handle<DataPipeHolder> Create(
|
||||
v8::Isolate* isolate,
|
||||
|
||||
@@ -22,41 +22,45 @@
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
NSDistributedNotificationCenter* distCenter =
|
||||
NSDistributedNotificationCenter* distributed_center =
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
// A notification that the screen was locked.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenLocked:)
|
||||
name:@"com.apple.screenIsLocked"
|
||||
object:nil];
|
||||
[distributed_center addObserver:self
|
||||
selector:@selector(onScreenLocked:)
|
||||
name:@"com.apple.screenIsLocked"
|
||||
object:nil];
|
||||
// A notification that the screen was unlocked by the user.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenUnlocked:)
|
||||
name:@"com.apple.screenIsUnlocked"
|
||||
object:nil];
|
||||
[distributed_center addObserver:self
|
||||
selector:@selector(onScreenUnlocked:)
|
||||
name:@"com.apple.screenIsUnlocked"
|
||||
object:nil];
|
||||
// A notification that the workspace posts before the machine goes to sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isSuspending:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
[distributed_center addObserver:self
|
||||
selector:@selector(isSuspending:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
// A notification that the workspace posts when the machine wakes from
|
||||
// sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isResuming:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
[distributed_center addObserver:self
|
||||
selector:@selector(isResuming:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
|
||||
NSNotificationCenter* shared_center =
|
||||
[[NSWorkspace sharedWorkspace] notificationCenter];
|
||||
|
||||
// A notification that the workspace posts when the user session becomes
|
||||
// active.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onUserDidBecomeActive:)
|
||||
name:NSWorkspaceSessionDidBecomeActiveNotification
|
||||
object:nil];
|
||||
[shared_center addObserver:self
|
||||
selector:@selector(onUserDidBecomeActive:)
|
||||
name:NSWorkspaceSessionDidBecomeActiveNotification
|
||||
object:nil];
|
||||
// A notification that the workspace posts when the user session becomes
|
||||
// inactive.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onUserDidResignActive:)
|
||||
name:NSWorkspaceSessionDidResignActiveNotification
|
||||
object:nil];
|
||||
[shared_center addObserver:self
|
||||
selector:@selector(onUserDidResignActive:)
|
||||
name:NSWorkspaceSessionDidResignActiveNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ gin::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
}
|
||||
|
||||
const char* PowerSaveBlocker::GetTypeName() {
|
||||
return "PowerSaveBlocker";
|
||||
}
|
||||
|
||||
} // namespace electron::api
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -20,10 +20,10 @@ class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
|
||||
static gin::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
// disable copy
|
||||
PowerSaveBlocker(const PowerSaveBlocker&) = delete;
|
||||
|
||||
@@ -72,7 +72,17 @@ WebFrameMain* WebFrameMain::FromFrameTreeNodeId(int frame_tree_node_id) {
|
||||
|
||||
// static
|
||||
WebFrameMain* WebFrameMain::FromRenderFrameHost(content::RenderFrameHost* rfh) {
|
||||
return rfh ? FromFrameTreeNodeId(rfh->GetFrameTreeNodeId()) : nullptr;
|
||||
if (!rfh)
|
||||
return nullptr;
|
||||
|
||||
// TODO(codebytere): remove after refactoring away from FrameTreeNodeId as map
|
||||
// key.
|
||||
auto* ftn =
|
||||
static_cast<content::RenderFrameHostImpl*>(rfh)->frame_tree_node();
|
||||
if (!ftn)
|
||||
return nullptr;
|
||||
|
||||
return FromFrameTreeNodeId(rfh->GetFrameTreeNodeId());
|
||||
}
|
||||
|
||||
gin::WrapperInfo WebFrameMain::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
@@ -358,8 +368,9 @@ gin::Handle<WebFrameMain> WebFrameMain::New(v8::Isolate* isolate) {
|
||||
// static
|
||||
gin::Handle<WebFrameMain> WebFrameMain::From(v8::Isolate* isolate,
|
||||
content::RenderFrameHost* rfh) {
|
||||
if (rfh == nullptr)
|
||||
if (!rfh)
|
||||
return gin::Handle<WebFrameMain>();
|
||||
|
||||
auto* web_frame = FromRenderFrameHost(rfh);
|
||||
if (web_frame)
|
||||
return gin::CreateHandle(isolate, web_frame);
|
||||
@@ -376,12 +387,14 @@ gin::Handle<WebFrameMain> WebFrameMain::From(v8::Isolate* isolate,
|
||||
gin::Handle<WebFrameMain> WebFrameMain::FromOrNull(
|
||||
v8::Isolate* isolate,
|
||||
content::RenderFrameHost* rfh) {
|
||||
if (rfh == nullptr)
|
||||
if (!rfh)
|
||||
return gin::Handle<WebFrameMain>();
|
||||
|
||||
auto* web_frame = FromRenderFrameHost(rfh);
|
||||
if (web_frame)
|
||||
return gin::CreateHandle(isolate, web_frame);
|
||||
return gin::Handle<WebFrameMain>();
|
||||
if (!web_frame)
|
||||
return gin::Handle<WebFrameMain>();
|
||||
|
||||
return gin::CreateHandle(isolate, web_frame);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -24,8 +24,6 @@ namespace electron::api {
|
||||
|
||||
class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
public:
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
|
||||
// Return the WebRequest object attached to |browser_context|, create if there
|
||||
// is no one.
|
||||
// Note that the lifetime of WebRequest object is managed by Session, instead
|
||||
@@ -44,6 +42,7 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
||||
content::BrowserContext* browser_context);
|
||||
|
||||
// gin::Wrappable:
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
@@ -53,9 +53,9 @@ class MessagePort : public gin::Wrappable<MessagePort>,
|
||||
bool* threw_exception);
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -93,6 +93,9 @@ api::Session* SerialChooserController::GetSession() {
|
||||
|
||||
void SerialChooserController::OnPortAdded(
|
||||
const device::mojom::SerialPortInfo& port) {
|
||||
if (!FilterMatchesAny(port))
|
||||
return;
|
||||
|
||||
ports_.push_back(port.Clone());
|
||||
api::Session* session = GetSession();
|
||||
if (session) {
|
||||
|
||||
@@ -182,6 +182,8 @@ class JSChunkedDataPipeGetter : public gin::Wrappable<JSChunkedDataPipeGetter>,
|
||||
.SetMethod("done", &JSChunkedDataPipeGetter::Done);
|
||||
}
|
||||
|
||||
const char* GetTypeName() override { return "JSChunkedDataPipeGetter"; }
|
||||
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
~JSChunkedDataPipeGetter() override = default;
|
||||
|
||||
|
||||
@@ -271,6 +271,8 @@ class ChunkedDataPipeReadableStream
|
||||
.SetMethod("read", &ChunkedDataPipeReadableStream::Read);
|
||||
}
|
||||
|
||||
const char* GetTypeName() override { return "ChunkedDataPipeReadableStream"; }
|
||||
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
|
||||
private:
|
||||
|
||||
@@ -28,4 +28,8 @@ Event::~Event() = default;
|
||||
|
||||
gin::WrapperInfo Event::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
const char* Event::GetTypeName() {
|
||||
return GetClassName();
|
||||
}
|
||||
|
||||
} // namespace gin_helper::internal
|
||||
|
||||
@@ -31,6 +31,7 @@ class Event : public gin::Wrappable<Event>,
|
||||
|
||||
// gin::Wrappable
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
const char* GetTypeName() override;
|
||||
|
||||
~Event() override;
|
||||
|
||||
|
||||
@@ -642,8 +642,7 @@ std::shared_ptr<node::Environment> NodeBindings::CreateEnvironment(
|
||||
v8::TryCatch try_catch(isolate);
|
||||
env = node::CreateEnvironment(
|
||||
static_cast<node::IsolateData*>(isolate_data), context, args, exec_args,
|
||||
static_cast<node::EnvironmentFlags::Flags>(flags), {}, {},
|
||||
&OnNodePreload);
|
||||
static_cast<node::EnvironmentFlags::Flags>(flags));
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
std::string err_msg =
|
||||
@@ -775,7 +774,7 @@ std::shared_ptr<node::Environment> NodeBindings::CreateEnvironment(
|
||||
}
|
||||
|
||||
void NodeBindings::LoadEnvironment(node::Environment* env) {
|
||||
node::LoadEnvironment(env, node::StartExecutionCallback{});
|
||||
node::LoadEnvironment(env, node::StartExecutionCallback{}, &OnNodePreload);
|
||||
gin_helper::EmitEvent(env->isolate(), env->process_object(), "loaded");
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +336,8 @@ void ShowItemInFolder(const base::FilePath& full_path) {
|
||||
base::ThreadPool::CreateCOMSTATaskRunner(
|
||||
{base::MayBlock(), base::TaskPriority::USER_BLOCKING})
|
||||
->PostTask(FROM_HERE,
|
||||
base::BindOnce(&ShowItemInFolderOnWorkerThread, full_path));
|
||||
base::BindOnce(&ShowItemInFolderOnWorkerThread,
|
||||
full_path.NormalizePathSeparators()));
|
||||
}
|
||||
|
||||
void OpenPath(const base::FilePath& full_path, OpenCallback callback) {
|
||||
@@ -344,9 +345,11 @@ void OpenPath(const base::FilePath& full_path, OpenCallback callback) {
|
||||
|
||||
base::ThreadPool::CreateCOMSTATaskRunner(
|
||||
{base::MayBlock(), base::TaskPriority::USER_BLOCKING})
|
||||
->PostTaskAndReplyWithResult(FROM_HERE,
|
||||
base::BindOnce(&OpenPathOnThread, full_path),
|
||||
std::move(callback));
|
||||
->PostTaskAndReplyWithResult(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&OpenPathOnThread,
|
||||
full_path.NormalizePathSeparators()),
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void OpenExternal(const GURL& url,
|
||||
|
||||
@@ -25,9 +25,7 @@ describe('setDisplayMediaRequestHandler', () => {
|
||||
// error message:
|
||||
// [ERROR:video_capture_device_client.cc(659)] error@ OnStart@content/browser/media/capture/desktop_capture_device_mac.cc:98, CGDisplayStreamCreate failed, OS message: Value too large to be stored in data type (84)
|
||||
// This is possibly related to the OS/VM setup that CircleCI uses for macOS.
|
||||
// Our arm64 runners are in @jkleinsc's office, and are real machines, so the
|
||||
// test works there.
|
||||
ifit(!(process.platform === 'darwin' && process.arch === 'x64'))('works when calling getDisplayMedia', async function () {
|
||||
ifit(process.platform !== 'darwin')('works when calling getDisplayMedia', async function () {
|
||||
if ((await desktopCapturer.getSources({ types: ['screen'] })).length === 0) {
|
||||
return this.skip();
|
||||
}
|
||||
@@ -306,7 +304,7 @@ describe('setDisplayMediaRequestHandler', () => {
|
||||
expect(ok).to.be.true(message);
|
||||
});
|
||||
|
||||
ifit(!(process.platform === 'darwin' && process.arch === 'x64'))('can supply a screen response to preferCurrentTab', async () => {
|
||||
ifit(process.platform !== 'darwin')('can supply a screen response to preferCurrentTab', async () => {
|
||||
const ses = session.fromPartition('' + Math.random());
|
||||
let requestHandlerCalled = false;
|
||||
ses.setDisplayMediaRequestHandler(async (request, callback) => {
|
||||
|
||||
@@ -188,11 +188,32 @@ describe('webContents module', () => {
|
||||
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('does not throw when options are not passed', () => {
|
||||
expect(() => {
|
||||
w.webContents.print();
|
||||
}).not.to.throw();
|
||||
|
||||
expect(() => {
|
||||
w.webContents.print(undefined);
|
||||
}).not.to.throw();
|
||||
});
|
||||
|
||||
it('does not throw when options object is empty', () => {
|
||||
expect(() => {
|
||||
w.webContents.print({});
|
||||
}).not.to.throw();
|
||||
});
|
||||
|
||||
it('throws when invalid settings are passed', () => {
|
||||
expect(() => {
|
||||
// @ts-ignore this line is intentionally incorrect
|
||||
w.webContents.print(true);
|
||||
}).to.throw('webContents.print(): Invalid print settings specified.');
|
||||
|
||||
expect(() => {
|
||||
// @ts-ignore this line is intentionally incorrect
|
||||
w.webContents.print(null);
|
||||
}).to.throw('webContents.print(): Invalid print settings specified.');
|
||||
});
|
||||
|
||||
it('throws when an invalid pageSize is passed', () => {
|
||||
@@ -2504,18 +2525,18 @@ describe('webContents module', () => {
|
||||
it('emits when moveTo is called', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadURL('about:blank');
|
||||
w.webContents.executeJavaScript('window.moveTo(100, 100)', true);
|
||||
w.webContents.executeJavaScript('window.moveTo(50, 50)', true);
|
||||
const [, rect] = await once(w.webContents, 'content-bounds-updated') as [any, Electron.Rectangle];
|
||||
const { width, height } = w.getBounds();
|
||||
expect(rect).to.deep.equal({
|
||||
x: 100,
|
||||
y: 100,
|
||||
x: 50,
|
||||
y: 50,
|
||||
width,
|
||||
height
|
||||
});
|
||||
await new Promise(setImmediate);
|
||||
expect(w.getBounds().x).to.equal(100);
|
||||
expect(w.getBounds().y).to.equal(100);
|
||||
expect(w.getBounds().x).to.equal(50);
|
||||
expect(w.getBounds().y).to.equal(50);
|
||||
});
|
||||
|
||||
it('emits when resizeTo is called', async () => {
|
||||
|
||||
@@ -2114,7 +2114,8 @@ describe('chromium features', () => {
|
||||
'chrome://gpu',
|
||||
'chrome://media-internals',
|
||||
'chrome://tracing',
|
||||
'chrome://webrtc-internals'
|
||||
'chrome://webrtc-internals',
|
||||
'chrome://process-internals'
|
||||
];
|
||||
|
||||
for (const url of urls) {
|
||||
@@ -2122,8 +2123,9 @@ describe('chromium features', () => {
|
||||
it('loads the page successfully', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
await w.loadURL(url);
|
||||
const host = url.substring('chrome://'.length);
|
||||
const pageExists = await w.webContents.executeJavaScript(
|
||||
"window.hasOwnProperty('chrome') && window.chrome.hasOwnProperty('send')"
|
||||
`window.hasOwnProperty('chrome') && window.location.host === '${host}'`
|
||||
);
|
||||
expect(pageExists).to.be.true();
|
||||
});
|
||||
|
||||
20
spec/fixtures/module/dynamic-import.js
vendored
Normal file
20
spec/fixtures/module/dynamic-import.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
const repl = require('node:repl');
|
||||
const { Writable } = require('node:stream');
|
||||
|
||||
const r = repl.start();
|
||||
|
||||
r.output = new Writable({ write () { } });
|
||||
|
||||
const sleep = async (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
async function main () {
|
||||
let x = 0;
|
||||
while (x < 50) {
|
||||
await sleep(0);
|
||||
r.write('(new Function(\'import("")\'))()\n');
|
||||
x += 1;
|
||||
}
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -917,6 +917,12 @@ describe('node feature', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not crash when dynamically importing inside a function', () => {
|
||||
const file = path.resolve(fixtures, 'module', 'dynamic-import.js');
|
||||
const { status } = childProcess.spawnSync(process.execPath, [file], { stdio: 'inherit' });
|
||||
expect(status).to.equal(0);
|
||||
});
|
||||
|
||||
it('Can find a module using a package.json main field', () => {
|
||||
const result = childProcess.spawnSync(process.execPath, [path.resolve(fixtures, 'api', 'electron-main-module', 'app.asar')], { stdio: 'inherit' });
|
||||
expect(result.status).to.equal(0);
|
||||
|
||||
Reference in New Issue
Block a user