Compare commits

..

24 Commits

Author SHA1 Message Date
trop[bot]
f7e22ed743 fix: child window may have opener removed (#38932)
* fix: child window may have opener removed

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* Update chromium-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-06-27 11:34:12 -04:00
Charles Kerr
437bf7d1fd refactor: api web contents ownership (#38894)
refactor: api web contents ownership (#38695)

* refactor: aggregate api::WebContents::exclusive_access_manager_ directly

* refactor: make WebContents::devtools_file_system_indexer_ scoped_refptr const

* refactor: make WebContents::file_task_runner_ scoped_refptr const

* refactor: make WebContents::print_task_runner_ scoped_refptr const
2023-06-22 13:01:27 -05:00
trop[bot]
d0b2a4e48f refactor: prefer base::Contains() over find() + end() (#38890)
refactor: prefer base::Contains() over find() + end() (#38443)

* refactor: use base::Contains() in KeyWeakMap::Has()

* refactor: use base::Contains() in WebRequest::RequestFilter::MatchesType()

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in DeepFreeze()

* refactor: use base::Contains() in Clipboard::Read()

* Revert "refactor: use base::Contains() in BaseWindow::AddBrowserView()"
This reverts commit 60152359d3978451ebdd7c8eed602c2fb8a9cafa.

* refactor: use base::Contains() in BaseWindow::AddBrowserView()

* refactor: use base::Contains() in IsDevToolsFileSystemAdded()

* refactor: use base::Contains() in MessagePort::DisentanglePorts()

* refactor: use base::Contains() in PowerSaveBlocker::IsStarted()

* refactor: use base::Contains() in SpellCheckClient::OnSpellCheckDone()

* refactor: use base::Contains() in ShowTaskDialogWstr()

* refactor: use base::Contains() in PrintViewManagerElectron::ScriptedPrint()

* refactor: use base::Contains() in PrintViewManagerElectron::DidGetPrintedPagesCount()

* refactor: use base::Contains() in NativeWindow::AddDraggableRegionProvider()

* refactor: use base::Contains() in ElectronBindings::ActivateUVLoop()

* refactor: use base::Contains() in NativeWindowViews::IsVisibleOnAllWorkspaces()

* refactor: use base::Contains() in HidChooserController::OnDeviceAdded()

* refactor: use base::Contains() in ElectronSandboxedRendererClient::WillReleaseScriptContext()

* refactor: use base::Contains() in ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread()

* refactor: use base::Contains() in GlobalShortcut::OnKeyPressed()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-22 13:06:35 +02:00
trop[bot]
192295697e fix: crash calling BrowserWindow.removeBrowserView() with destroyed webContents (#38884)
fix: crash calling removeBrowserView() with destroyed webContents

https://github.com/electron/electron/issues/37642

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-22 11:22:30 +02:00
trop[bot]
e47bdb67f8 fix: set minimize visibility true with enable (#38881)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2023-06-22 10:31:06 +02:00
trop[bot]
25dee92c57 refactor: remove unused InspectableWebContentsView::GetWebView() (#38819)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 12:43:47 -05:00
trop[bot]
053031e96c refactor: constexpr lookup tables (#38807)
* refactor: constexpr lookup tables (#38771)

* refactor: use a constexpr lookup table in GetPathConstant()

* refactor: use a constexpr lookup table in SystemPreferences::GetColor()

* refactor: use a constexpr lookup table in SimpleURLLoaderWrapper::Create()

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fix: use MakeFixedFlatMap() instead of MakeFixedFlatMapSorted()

The latter compiles faster but does not exist in 24-x-y

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/4296340

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-16 10:03:09 +02:00
trop[bot]
1e64527ec3 feat: support node: prefixed requires in sandboxed renderer preloads (#38727)
feat: support node: prefixed requires in sandboxed renderer preloads

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-06-15 12:00:01 +02:00
trop[bot]
1645aece38 fix: preferCSSPageSize error type (#38792)
fix: preferCSSPageSize error type

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-14 11:03:13 -07:00
Pedro Pontes
1f66b20392 chore: cherry-pick 3 changes from Release-2-M114 (#38787)
* chore: [24-x-y] cherry-pick 1 changes from Release-2-M114

* 2e76270cf65e from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-14 11:02:59 -07:00
trop[bot]
8df8cad3a0 refactor: use compile-time cli arg sets. (#38770)
We're currently building these on the heap with `std::set<std::string>`
but this can be a very small compile-time container instead.

Marking as 'refactor' rather than 'perf' since this isn't called often,
but moving from heap to compile-time is good and using this container
makes the code more readable.
2023-06-13 16:28:30 -05:00
trop[bot]
6d111ddbe3 fix: reparenting UAF crash on macOS (#38677)
* fix: reparenting UAF crash on macOS

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* Update api-browser-window-spec.ts

* Update api-browser-window-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-13 15:54:09 -04:00
trop[bot]
2c9f2e81e8 perf: prefer base::StringPiece over std::string for build-time strings (#38736)
* perf: use base::StringPiece in InclusionStatusToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in ErrorCodeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in MessageSourceToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in CursorTypeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in MediaStreamTypeToString()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in ModifiersToArray()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* perf: use base::StringPiece in WebFrameRenderer::MaybeGetRenderFrame()

The strings are all build-time constants and this is a private function

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-12 16:22:15 -05:00
trop[bot]
14c6c397d0 fix: menu bar visibility when exiting full screen (#38681)
* fix:visibility of menu bar when exiting full screen

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* Modify comments

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* add menu bar visibility test

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* format code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* change code

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* platform related in test

Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>

* Update api-browser-window-spec.ts

* Update api-browser-window-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: wugaosheng <wugaosheng@kylinos.cn>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-12 15:50:07 +02:00
Keeley Hammond
3ce4c24c4b chore: cherry-pick 8 changes from Release-0-M114 (#38536)
* chore: [24-x-y] cherry-pick 4 changes from Release-0-M114

* e6b75a8b4900 from chromium
* 3b0607d14060 from v8
* 9c6dfc733fce from v8
* ea1cd76358e0 from chromium

* chore: remove one invalid patch, fix another

* chore: add missing backports.

* chore: update patches

---------

Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2023-06-09 17:29:30 -07:00
trop[bot]
97018c7be1 build: use upstream's presubmit cpplint filters. (#38687)
* build: use upstream's presubmit cpplint filters.

Our list of filters has fallen out-of-sync with upstream tests and so
our checks don't match those in the Google + Chromium guides.

The checks in this PR come from depot_tools and are copied manually
since the depot_tools code is python but our linter is js. 🤷
Perhaps we should rewrite in python?

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fixup! build: use upstream's presubmit cpplint filters.

chore: make linter happy with my linter changes

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-09 12:27:00 -07:00
trop[bot]
42c90f3eeb build: move uploadIndexJson to just before publishRelease (#38701)
* build: move uploadIndexJson to just before publishRelease

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: move uploadNodeShasums as well

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* build: upload node checksums before validating them

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-06-09 12:22:22 -07:00
trop[bot]
bb2f62f95f refactor: add SessionPreferences::CreateForBrowserContext() (#38712)
Copy the NativeWindowRelay::CreateForWebContents() idiom
to simplify SessionPreferences's constructor and lifecycle.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-09 12:21:02 -07:00
Samuel Attard
b60166eddc chore: cherry-pick 94af9d13a14b from chromium (#38711)
* chore: cherry-pick 94af9d13a14b from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-09 12:08:56 -05:00
trop[bot]
1b762ef8a1 fix: dangling pointer warning when updating menus (#38689)
fix: dangling raw_ptr warning when updating menus

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-08 13:28:23 -04:00
trop[bot]
3815e90434 fix: bad error passing webContents.print(null) (#38640)
fix: bad error passing webContents.print(null)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-07 23:53:05 -07:00
trop[bot]
65fba6f51b refactor: remove unused OffScreenRenderWidgetHostView fields (#38651)
* refactor: remove unused field OffScreenRenderWidgetHostView::last_time_

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused field OffScreenRenderWidgetHostView::last_scroll_offset_

Unused since 1a9e253

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: remove unused field OffScreenRenderWidgetHostView::paint_callback_running_

assigned to, but unread, since 81bf158

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-06-07 23:50:38 -07:00
Pedro Pontes
5e6d99a6af chore: cherry-pick 2 changes from Release-1-M114 (#38654)
* chore: [24-x-y] cherry-pick 2 changes from Release-1-M114

* 73af1a19a901 from v8
* 0035a4a8dac2 from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-07 23:49:37 -07:00
trop[bot]
bfb3b6d9a4 build: improve error output in release.js (#38664)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-07 23:48:17 -07:00
74 changed files with 2295 additions and 390 deletions

View File

@@ -51,6 +51,12 @@ but can only import a subset of Electron and Node's built-in modules:
* [`timers`](https://nodejs.org/api/timers.html)
* [`url`](https://nodejs.org/api/url.html)
[node: imports](https://nodejs.org/api/esm.html#node-imports) are supported as well:
* [`node:events`](https://nodejs.org/api/events.html)
* [`node:timers`](https://nodejs.org/api/timers.html)
* [`node:url`](https://nodejs.org/api/url.html)
In addition, the preload script also polyfills certain Node.js primitives as globals:
* [`Buffer`](https://nodejs.org/api/buffer.html)

View File

@@ -317,7 +317,7 @@ WebContents.prototype.printToPDF = async function (options) {
if (options.preferCSSPageSize !== undefined) {
if (typeof options.preferCSSPageSize !== 'boolean') {
return Promise.reject(new Error('footerTemplate must be a String'));
return Promise.reject(new Error('preferCSSPageSize must be a Boolean'));
}
printSettings.preferCSSPageSize = options.preferCSSPageSize;
}
@@ -335,36 +335,34 @@ WebContents.prototype.printToPDF = async function (options) {
}
};
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions = {}, callback) {
// TODO(codebytere): deduplicate argument sanitization by moving rest of
// print param logic into new file shared between printToPDF and print
if (typeof options === 'object') {
// Optionally set size for PDF.
if (options.pageSize !== undefined) {
const pageSize = options.pageSize;
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
}
// Dimensions in Microns - 1 meter = 10^6 microns
const height = Math.ceil(pageSize.height);
const width = Math.ceil(pageSize.width);
if (!isValidCustomPageSize(width, height)) {
throw new Error('height and width properties must be minimum 352 microns.');
}
options.mediaSize = {
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: height,
width_microns: width
};
} else if (PDFPageSizes[pageSize]) {
options.mediaSize = PDFPageSizes[pageSize];
} else {
throw new Error(`Unsupported pageSize: ${pageSize}`);
// TODO(codebytere): deduplicate argument sanitization by moving rest of
// print param logic into new file shared between printToPDF and print
WebContents.prototype.print = function (printOptions: ElectronInternal.WebContentsPrintOptions, callback) {
const options = printOptions ?? {};
if (options.pageSize) {
const pageSize = options.pageSize;
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
}
// Dimensions in Microns - 1 meter = 10^6 microns
const height = Math.ceil(pageSize.height);
const width = Math.ceil(pageSize.width);
if (!isValidCustomPageSize(width, height)) {
throw new Error('height and width properties must be minimum 352 microns.');
}
options.mediaSize = {
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: height,
width_microns: width
};
} else if (PDFPageSizes[pageSize]) {
options.mediaSize = PDFPageSizes[pageSize];
} else {
throw new Error(`Unsupported pageSize: ${pageSize}`);
}
}

View File

@@ -33,12 +33,15 @@ const loadedModules = new Map<string, any>([
['electron', electron],
['electron/common', electron],
['electron/renderer', electron],
['events', events]
['events', events],
['node:events', events]
]);
const loadableModules = new Map<string, Function>([
['timers', () => require('timers')],
['url', () => require('url')]
['node:timers', () => require('timers')],
['url', () => require('url')],
['node:url', () => require('url')]
]);
// Pass different process object to the preload script.

View File

@@ -128,3 +128,8 @@ fix_x11_window_restore_minimized_maximized_window.patch
chore_defer_usb_service_getdevices_request_until_usb_service_is.patch
revert_x11_keep_windowcache_alive_for_a_time_interval.patch
cherry-pick-ec53103cc72d.patch
cherry-pick-94af9d13a14b.patch
cherry-pick-ea1cd76358e0.patch
m114_merge_fix_a_crash_caused_by_calling_trace_event.patch
mojoipcz_copy_incoming_messages_early.patch
base_do_not_use_va_args_twice_in_asprintf.patch

View File

@@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benoit Lize <lizeb@chromium.org>
Date: Fri, 9 Jun 2023 17:59:08 +0000
Subject: Do not use va_args twice in asprintf()
(cherry picked from commit 3cff0cb19a6d01cbdd9932f43dabaaeda9c0330a)
Bug: 1450536
Change-Id: Ib34d96935278869a63897f9a1c66afc98865d90f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4579347
Reviewed-by: Egor Pasko <pasko@chromium.org>
Commit-Queue: Benoit Lize <lizeb@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1151796}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604070
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/branch-heads/5735@{#1224}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
index 621873126602463a09efca1bf1548ed10910d323..de2af6d7d54e254b9e7b8264b53d30a338fb13e8 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
+++ b/base/allocator/partition_allocator/shim/allocator_shim_override_linker_wrapped_symbols.h
@@ -123,13 +123,21 @@ SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
const char* fmt,
va_list va_args) {
+ // There are cases where we need to use the list of arguments twice, namely
+ // when the original buffer is too small. It is not allowed to walk the list
+ // twice, so make a copy for the second invocation of vsnprintf().
+ va_list va_args_copy;
+ va_copy(va_args_copy, va_args);
+
constexpr int kInitialSize = 128;
*strp = static_cast<char*>(
malloc(kInitialSize)); // Our malloc() doesn't return nullptr.
int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
- if (actual_size < 0)
+ if (actual_size < 0) {
+ va_end(va_args_copy);
return actual_size;
+ }
*strp =
static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
@@ -139,9 +147,14 @@ SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
//
// This is very lightly used in Chromium in practice, see crbug.com/116558 for
// details.
- if (actual_size >= kInitialSize)
- return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
-
+ if (actual_size >= kInitialSize) {
+ int ret = vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt,
+ va_args_copy);
+ va_end(va_args_copy);
+ return ret;
+ }
+
+ va_end(va_args_copy);
return actual_size;
}
diff --git a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
index dcf26fa5fc6d51de6276aa6fdcc4691f781c4bfd..fd46a15799864acaf58ef57315606bf515b48b15 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
@@ -734,6 +734,28 @@ TEST_F(AllocatorShimTest, InterceptVasprintf) {
// Should not crash.
}
+TEST_F(AllocatorShimTest, InterceptLongVasprintf) {
+ char* str = nullptr;
+ const char* lorem_ipsum =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. "
+ "Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, "
+ "ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula "
+ "massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci "
+ "nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit "
+ "amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat "
+ "in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero "
+ "pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo "
+ "in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue "
+ "blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus "
+ "et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed "
+ "pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales "
+ "hendrerit.";
+ int err = asprintf(&str, "%s", lorem_ipsum);
+ EXPECT_EQ(err, static_cast<int>(strlen(lorem_ipsum)));
+ EXPECT_TRUE(str);
+ free(str);
+}
+
#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#endif // BUILDFLAG(IS_ANDROID)

View File

@@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pavlotsky <ivan.pavlotsky@lge.com>
Date: Mon, 1 May 2023 07:48:23 +0000
Subject: Check nullptr in ZWPTextInputWrapperV1::Activate()
After the CL https://crrev.com/c/4160118 a crash occurres on the
wl::get_version_of_object() call in ZWPTextInputWrapperV1::Activate()
when |ZWPTextInputWrapperV1::extended_obj_| is not set.
Added nullptr check to fix it.
Bug: b:251677220, 1431532
Change-Id: Ia5606f1c0d08f552f1091b2a9350655f4bdac939
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4423030
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Maksim Sisov <msisov@igalia.com>
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1137771}
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
index d577ac4f822901340281c48bc754425484f28f48..b9e508824c7cb17c0673007532f88242a99fa5df 100644
--- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
+++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
@@ -156,8 +156,9 @@ void ZWPTextInputWrapperV1::Reset() {
void ZWPTextInputWrapperV1::Activate(WaylandWindow* window,
TextInputClient::FocusReason reason) {
DCHECK(connection_->seat());
- if (wl::get_version_of_object(extended_obj_.get()) >=
- ZCR_EXTENDED_TEXT_INPUT_V1_SET_FOCUS_REASON_SINCE_VERSION) {
+ if (extended_obj_.get() &&
+ wl::get_version_of_object(extended_obj_.get()) >=
+ ZCR_EXTENDED_TEXT_INPUT_V1_SET_FOCUS_REASON_SINCE_VERSION) {
absl::optional<uint32_t> wayland_focus_reason;
switch (reason) {
case ui::TextInputClient::FocusReason::FOCUS_REASON_NONE:

View File

@@ -0,0 +1,200 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kevin McNee <mcnee@chromium.org>
Date: Tue, 23 May 2023 15:46:16 +0000
Subject: M114: Compute all webview find options before cloning them
Compute all webview find options before cloning them
In WebViewFindHelper::Find, we're cloning the find options before we've
set the value for `new_session`. For requests that are part of the same
session, in WebViewFindHelper::FindReply, we're using the incorrect
value for `new_session` and we're destroying the FindInfo for what we
think is a previous session but is actually for the request we're
currently processing.
We now fully compute the options before cloning them.
(cherry picked from commit bb8e17b942b8b1de0a58b2dce34197e00a3b6525)
Bug: 1443401
Change-Id: Ife6747aedabaf74f9a4855a173349ffe612b6f95
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4533923
Reviewed-by: James Maclean <wjmaclean@chromium.org>
Commit-Queue: James Maclean <wjmaclean@chromium.org>
Auto-Submit: Kevin McNee <mcnee@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1145265}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4556646
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5735@{#941}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 7762464ba5eb84702021f8328e455e0d05e87b46..c5167c135a7e41705ac018d3aec568c65fdcb0dc 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -3983,6 +3983,11 @@ IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_testFindInMultipleWebViews) {
TestHelper("testFindInMultipleWebViews", "web_view/shim", NO_TEST_SERVER);
}
+IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestFindAfterTerminate) {
+ content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
+ TestHelper("testFindAfterTerminate", "web_view/shim", NO_TEST_SERVER);
+}
+
IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
index 12c29cc718765d0f04b81430011569786587f677..c252e13563dff2660af1187ce3a16d5997f0679d 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -2868,6 +2868,20 @@ function testFindInMultipleWebViews() {
});
}
+function testFindAfterTerminate() {
+ let webview = new WebView();
+ webview.src = 'data:text/html,<body><iframe></iframe></body>';
+ webview.addEventListener('loadstop', () => {
+ webview.find('A');
+ webview.terminate();
+ webview.find('B', {'backward': true});
+ webview.find('B', {'backward': true}, (results) => {
+ embedder.test.succeed();
+ });
+ });
+ document.body.appendChild(webview);
+}
+
function testLoadDataAPI() {
var webview = new WebView();
webview.src = 'about:blank';
@@ -3644,6 +3658,7 @@ embedder.test.testList = {
'testFindAPI': testFindAPI,
'testFindAPI_findupdate': testFindAPI_findupdate,
'testFindInMultipleWebViews': testFindInMultipleWebViews,
+ 'testFindAfterTerminate': testFindAfterTerminate,
'testLoadDataAPI': testLoadDataAPI,
'testLoadDataAPIAccessibleResources': testLoadDataAPIAccessibleResources,
'testResizeEvents': testResizeEvents,
diff --git a/extensions/browser/guest_view/web_view/web_view_find_helper.cc b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
index 0913a8f3da48420c6b0fd328d37268ca5b0e6e63..3e70549084be8537198996c07d2f61c6308ad893 100644
--- a/extensions/browser/guest_view/web_view/web_view_find_helper.cc
+++ b/extensions/browser/guest_view/web_view/web_view_find_helper.cc
@@ -36,12 +36,12 @@ void WebViewFindHelper::CancelAllFindSessions() {
void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
bool final_update) {
- DCHECK(find_update_event_.get());
+ CHECK(find_update_event_);
base::Value::Dict args;
find_update_event_->PrepareResults(args);
args.Set(webview::kFindCanceled, canceled);
args.Set(webview::kFindFinalUpdate, final_update);
- DCHECK(webview_guest_);
+ CHECK(webview_guest_);
webview_guest_->DispatchEventToView(std::make_unique<GuestViewEvent>(
webview::kEventFindReply, std::move(args)));
}
@@ -94,6 +94,17 @@ void WebViewFindHelper::Find(
// Need a new request_id for each new find request.
++current_find_request_id_;
+ if (current_find_session_) {
+ const std::u16string& current_search_text =
+ current_find_session_->search_text();
+ bool current_match_case = current_find_session_->options()->match_case;
+ options->new_session = current_search_text.empty() ||
+ current_search_text != search_text ||
+ current_match_case != options->match_case;
+ } else {
+ options->new_session = true;
+ }
+
// Stores the find request information by request_id so that its callback
// function can be called when the find results are available.
std::pair<FindInfoMap::iterator, bool> insert_result =
@@ -102,32 +113,19 @@ void WebViewFindHelper::Find(
base::MakeRefCounted<FindInfo>(current_find_request_id_, search_text,
options.Clone(), find_function)));
// No duplicate insertions.
- DCHECK(insert_result.second);
-
- blink::mojom::FindOptionsPtr full_options =
- insert_result.first->second->options().Clone();
-
- if (current_find_session_) {
- const std::u16string& current_search_text =
- current_find_session_->search_text();
- bool current_match_case = current_find_session_->options()->match_case;
- full_options->new_session = current_search_text.empty() ||
- current_search_text != search_text ||
- current_match_case != options->match_case;
- } else {
- full_options->new_session = true;
- }
+ CHECK(insert_result.second);
// Link find requests that are a part of the same find session.
- if (!full_options->new_session && current_find_session_) {
- DCHECK(current_find_request_id_ != current_find_session_->request_id());
+ if (!options->new_session && current_find_session_) {
+ CHECK(current_find_request_id_ != current_find_session_->request_id());
current_find_session_->AddFindNextRequest(
insert_result.first->second->AsWeakPtr());
}
// Update the current find session, if necessary.
- if (full_options->new_session)
+ if (options->new_session) {
current_find_session_ = insert_result.first->second;
+ }
// Handle the empty |search_text| case internally.
if (search_text.empty()) {
@@ -137,7 +135,7 @@ void WebViewFindHelper::Find(
}
guest_web_contents->Find(current_find_request_id_, search_text,
- std::move(full_options), /*skip_delay=*/true);
+ std::move(options), /*skip_delay=*/true);
}
void WebViewFindHelper::FindReply(int request_id,
@@ -152,14 +150,14 @@ void WebViewFindHelper::FindReply(int request_id,
return;
// This find request must be a part of an existing find session.
- DCHECK(current_find_session_);
+ CHECK(current_find_session_);
WebViewFindHelper::FindInfo* find_info = find_iterator->second.get();
// Handle canceled find requests.
if (find_info->options()->new_session &&
find_info_map_.begin()->first < request_id) {
- DCHECK_NE(current_find_session_->request_id(),
- find_info_map_.begin()->first);
+ CHECK_NE(current_find_session_->request_id(),
+ find_info_map_.begin()->first);
if (find_update_event_)
DispatchFindUpdateEvent(true /* canceled */, true /* final_update */);
EndFindSession(find_info_map_.begin()->first, true /* canceled */);
@@ -174,11 +172,12 @@ void WebViewFindHelper::FindReply(int request_id,
// Aggregate the find results.
find_info->AggregateResults(number_of_matches, selection_rect,
active_match_ordinal, final_update);
- find_update_event_->AggregateResults(number_of_matches, selection_rect,
- active_match_ordinal, final_update);
-
- // Propagate incremental results to the |findupdate| event.
- DispatchFindUpdateEvent(false /* canceled */, final_update);
+ if (find_update_event_) {
+ find_update_event_->AggregateResults(number_of_matches, selection_rect,
+ active_match_ordinal, final_update);
+ // Propagate incremental results to the |findupdate| event.
+ DispatchFindUpdateEvent(false /* canceled */, final_update);
+ }
// Call the callback functions of completed find requests.
if (final_update)

View File

@@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maggie Chen <magchen@chromium.org>
Date: Thu, 18 May 2023 00:20:34 +0000
Subject: Fix a crash caused by calling TRACE_EVENT
Now use literal constant for TRACE_EVENT. Passing a pointer instead of
string content to TRACE_EVENT causes a crash in ScopedTracer.
(cherry picked from commit 6f2e587807aff2306309025db1c15fc59290eb6f)
Bug: 1444195
Change-Id: I02aa1148d61e7596e9293ffc866135e99991e42e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4522164
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1144352}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4544885
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5735@{#749}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/ui/gl/swap_chain_presenter.cc b/ui/gl/swap_chain_presenter.cc
index a3263dd2fa9163ed98121ce62c216c176235f0ea..2665d9d3575e1c82698061d068858e77ee0afbbd 100644
--- a/ui/gl/swap_chain_presenter.cc
+++ b/ui/gl/swap_chain_presenter.cc
@@ -1701,10 +1701,8 @@ bool SwapChainPresenter::ReallocateSwapChain(
}
}
if (!use_yuv_swap_chain) {
- std::ostringstream trace_event_stream;
- trace_event_stream << "SwapChainPresenter::ReallocateSwapChain::"
- << DxgiFormatToString(swap_chain_format);
- TRACE_EVENT0("gpu", trace_event_stream.str().c_str());
+ TRACE_EVENT1("gpu", "SwapChainPresenter::ReallocateSwapChain::BGRA",
+ "format", DxgiFormatToString(swap_chain_format));
desc.Format = swap_chain_format;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO;

View File

@@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ken Rockot <rockot@google.com>
Date: Mon, 3 Apr 2023 19:43:13 +0000
Subject: MojoIpcz: Copy incoming messages early
Fixed: 1429720
Change-Id: Id6cb7269d3a3e9118cc6ff1579b56e18bf911c07
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4390758
Commit-Queue: Ken Rockot <rockot@google.com>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1125510}
diff --git a/mojo/core/ipcz_driver/mojo_message.cc b/mojo/core/ipcz_driver/mojo_message.cc
index da073af255795b37418b5030bf2f1cc2c0c0c7d1..e362f3db6003c9f75701b657fe32b7e65cd82661 100644
--- a/mojo/core/ipcz_driver/mojo_message.cc
+++ b/mojo/core/ipcz_driver/mojo_message.cc
@@ -109,23 +109,20 @@ void MojoMessage::SetParcel(ScopedIpczHandle parcel) {
// We always pass a parcel object in, so Begin/EndGet() must always succeed.
DCHECK_EQ(result, IPCZ_RESULT_OK);
+ if (num_bytes > 0) {
+ data_storage_.reset(
+ static_cast<uint8_t*>(base::AllocNonScannable(num_bytes)));
+ memcpy(data_storage_.get(), data, num_bytes);
+ } else {
+ data_storage_.reset();
+ }
+ data_ = {data_storage_.get(), num_bytes};
+ data_storage_size_ = num_bytes;
- // Grab only the handles.
handles_.resize(num_handles);
- result = GetIpczAPI().EndGet(parcel_.get(), 0, num_handles, IPCZ_NO_FLAGS,
- nullptr, handles_.data());
- DCHECK_EQ(result, IPCZ_RESULT_OK);
-
- // Now start a new two-phase get, which we'll leave active indefinitely for
- // `data_` to reference.
- result = GetIpczAPI().BeginGet(parcel_.get(), IPCZ_NO_FLAGS, nullptr, &data,
- &num_bytes, &num_handles);
+ result = GetIpczAPI().EndGet(parcel_.get(), num_bytes, num_handles,
+ IPCZ_NO_FLAGS, nullptr, handles_.data());
DCHECK_EQ(result, IPCZ_RESULT_OK);
-
- DCHECK_EQ(0u, num_handles);
- data_ = base::make_span(static_cast<uint8_t*>(const_cast<void*>(data)),
- num_bytes);
-
if (!FixUpDataPipeHandles(handles_)) {
// The handle list was malformed. Although this is a validation error, it
// is not safe to trigger MojoNotifyBadMessage from within MojoReadMessage,

View File

@@ -23,5 +23,7 @@
"src/electron/patches/ReactiveObjC": "src/third_party/squirrel.mac/vendor/ReactiveObjC",
"src/electron/patches/webrtc": "src/third_party/webrtc"
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/pdfium": "src/third_party/pdfium"
}

3
patches/pdfium/.patches Normal file
View File

@@ -0,0 +1,3 @@
m114_observe_cpwl_combobox_across_all_on_methods.patch
m114_observe_widget_across_setoptionselection_calls.patch
m114_always_check_return_code_from_cpwl_combobox_setpopup.patch

View File

@@ -0,0 +1,236 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Fri, 19 May 2023 18:41:31 +0000
Subject: Always check return code from CPWL_ComboBox::SetPopup().
Operation must not continue when false is returned.
Bug: chromium:1444238
Change-Id: Ic8c29653ac185ac80b6248203649ce05d0e10f06
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107390
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit 3eb3c4d77d4f9372f77aa4895b85a1d4e4755c89)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107812
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 5631822e0a342a6cba0f26fc45919168a74ec102..c84b7c071466e741cc4e6d113c1dc292ea685828 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -405,7 +405,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
// options.
switch (nChar) {
case pdfium::ascii::kReturn:
- SetPopup(!IsPopup());
+ if (!SetPopup(!IsPopup())) {
+ return false;
+ }
SetSelectText();
return true;
case pdfium::ascii::kSpace:
@@ -413,7 +415,9 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
// editable
if (!HasFlag(PCBS_ALLOWCUSTOMTEXT)) {
if (!IsPopup()) {
- SetPopup(/*bPopUp=*/true);
+ if (!SetPopup(/*bPopUp=*/true)) {
+ return false;
+ }
SetSelectText();
}
return true;
@@ -443,7 +447,7 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
if (child == m_pButton) {
- SetPopup(!m_bPopup);
+ (void)SetPopup(!m_bPopup);
// Note, |this| may no longer be viable at this point. If more work needs to
// be done, check the return value of SetPopup().
}
@@ -456,7 +460,7 @@ void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
SetSelectText();
SelectAllText();
m_pEdit->SetFocus();
- SetPopup(false);
+ (void)SetPopup(false);
// Note, |this| may no longer be viable at this point. If more work needs to
// be done, check the return value of SetPopup().
}
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
index bb8fa0ceca354b27b7699127ed10030ee9817fc5..87749fa7820bdd0cc7f098695071336fe55ef9c7 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.h
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
@@ -65,7 +65,7 @@ class CPWL_ComboBox final : public CPWL_Wnd {
void CreateListBox(const CreateParams& cp);
// Returns |true| iff this instance is still allocated.
- bool SetPopup(bool bPopup);
+ [[nodiscard]] bool SetPopup(bool bPopup);
UnownedPtr<CPWL_Edit> m_pEdit;
UnownedPtr<CPWL_CBButton> m_pButton;
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.evt b/testing/resources/javascript/xfa_specific/bug_1444238.evt
new file mode 100644
index 0000000000000000000000000000000000000000..adca35aa0d756e76eb395c5d60ba41b86c3d0090
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.evt
@@ -0,0 +1,3 @@
+mousedown,left,91,539
+mouseup,left,91,539
+charcode,32
diff --git a/testing/resources/javascript/xfa_specific/bug_1444238.in b/testing/resources/javascript/xfa_specific/bug_1444238.in
new file mode 100644
index 0000000000000000000000000000000000000000..675178c9446b0181c3633a4b5c9bc664bb4c127d
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_1444238.in
@@ -0,0 +1,149 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 4 0 R
+ /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 2
+ /Kids [
+ 32 0 R
+ 34 0 R
+ ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+ /XFA 43 0 R
+ /Fields [
+ 10 0 R
+ 11 0 R
+ ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Tx
+ /T (MyField5)
+ /V (myfield_5)
+ /Rect [0 500 600 600]
+>>
+% Fields
+{{object 11 0}} <<
+ /T (MyField3)
+ /Parent 4 0 R
+ /Kids [12 0 R]
+ /Opt [(a) (b) (c) (d)]
+ /V [(a) (b) (c)]
+>>
+endobj
+% Fields
+{{object 12 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Ch
+ /Ff 131072
+ /Parent 11 0 R
+ /Kids [13 0 R]
+>>
+endobj
+% Fields
+{{object 13 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /Parent 12 0 R
+ /Rect [0 400 600 600]
+>>
+endobj
+% Fields
+{{object 14 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /Parent 12 0 R
+ /Rect [100 400 500 500]
+>>
+endobj
+% Page number 2.
+{{object 32 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+>>
+stream
+var f5 = this.getField("MyField5");
+var f3 = this.getField("MyField3");
+f3.setFocus();
+this.__defineGetter__("pageNum",function o(){f5.setFocus(); f3.borderStyle="dashed"; f3.setFocus();});
+endstream
+endobj
+{{object 43 0}} <<
+ {{streamlen}}
+>>
+stream
+<?xml version="1.0" encoding="UTF-8"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+<config></config>
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.8/">
+ <subform layout="tb" locale="en_US">
+ <pageSet>
+ <pageArea id="Page1" name="Page1">
+ <contentArea h="268.939mm" w="203.2mm" x="6.35mm" y="6.35mm"/>
+ <medium long="792pt" short="612pt" stock="default"/>
+ </pageArea>
+ </pageSet>
+ <field h="9.0001mm" name="MyField3" w="47.625mm" x="120mm" y="120mm">
+ <ui>
+ <choiceList open="onEntry">
+ <border>
+ <edge/>
+ </border>
+ </choiceList>
+ </ui>
+ <items save="1">
+ <text>apples</text>
+ <text>bananas</text>
+ <text>pears</text>
+ </items>
+ <value>
+ <text>apples</text>
+ </value>
+ <event activity="preOpen">
+ <script contentType="application/x-javascript">
+ var aa = this.pageNum;
+ </script>
+ </event>
+ </field>
+ </subform>
+</template>
+</xdp:xdp>
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF

View File

@@ -0,0 +1,213 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Fri, 19 May 2023 20:05:10 +0000
Subject: Observe CPWL_ComboBox across all On* methods
Bug: chromium:1445426
Change-Id: I1d7ebf66fe170ca016c27a0df3ac4574e75c763c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107650
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
(cherry picked from commit 29c665ea4c61b089746c3f502c30fcb5f4b11486)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107811
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 29d1cea2bce2d91e975dc3a7ce4923d487f7de2a..5631822e0a342a6cba0f26fc45919168a74ec102 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -344,31 +344,42 @@ bool CPWL_ComboBox::OnKeyDown(FWL_VKEYCODE nKeyCode,
if (!m_pEdit)
return false;
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
m_nSelectItem = -1;
switch (nKeyCode) {
case FWL_VKEY_Up:
if (m_pList->GetCurSel() > 0) {
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (m_pList->IsMovementKey(nKeyCode)) {
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
return false;
+ }
SetSelectText();
}
}
return true;
case FWL_VKEY_Down:
if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (m_pList->IsMovementKey(nKeyCode)) {
- if (m_pList->OnMovementKeyDown(nKeyCode, nFlag))
+ if (m_pList->OnMovementKeyDown(nKeyCode, nFlag) || !thisObserved) {
return false;
+ }
SetSelectText();
}
}
@@ -416,10 +427,15 @@ bool CPWL_ComboBox::OnChar(uint16_t nChar, Mask<FWL_EVENTFLAG> nFlag) {
if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
return m_pEdit->OnChar(nChar, nFlag);
- if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag))
+ ObservedPtr<CPWL_Wnd> thisObserved(this);
+ if (GetFillerNotify()->OnPopupPreOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
- if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag))
+ }
+ if (GetFillerNotify()->OnPopupPostOpen(GetAttachedData(), nFlag) ||
+ !thisObserved) {
return false;
+ }
if (!m_pList->IsChar(nChar, nFlag))
return false;
return m_pList->OnCharNotify(nChar, nFlag);
diff --git a/testing/resources/javascript/bug_1445426.evt b/testing/resources/javascript/bug_1445426.evt
new file mode 100644
index 0000000000000000000000000000000000000000..265e85b0471b33509568238ccae30d2395b4b4ab
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.evt
@@ -0,0 +1,3 @@
+mousedown,left,202,697
+mouseup,left,202,697
+keycode,40
diff --git a/testing/resources/javascript/bug_1445426.in b/testing/resources/javascript/bug_1445426.in
new file mode 100644
index 0000000000000000000000000000000000000000..1483da72f5759e9f2c8fdb538d5c6fa0cd1611c5
--- /dev/null
+++ b/testing/resources/javascript/bug_1445426.in
@@ -0,0 +1,114 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 4 0 R
+ /OpenAction 40 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 2
+ /Kids [
+ 32 0 R
+ 34 0 R
+ ]
+>>
+endobj
+% Forms
+{{object 4 0}} <<
+ /Fields [
+ 10 0 R
+ 11 0 R
+ ]
+>>
+endobj
+% Fields
+{{object 10 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Tx
+ /T (Field_TextEdit)
+ /Rect [0 0 612 792]
+>>
+{{object 11 0}} <<
+ /T (Field_ComboBox)
+ /Parent 4 0 R
+ /Kids [12 0 R]
+ /Opt [(a) (b) (c) (d)]
+ /V [(a)]
+>>
+endobj
+{{object 12 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Ch
+ /Ff 131072
+ /Parent 11 0 R
+ /Kids [13 0 R]
+>>
+endobj
+{{object 13 0}} <<
+ /Parent 12 0 R
+ /Type /Annot
+ /Subtype /Widget
+ /Rect [0 0 612 792]
+ /AA << /K 20 0 R >>
+>>
+endobj
+% Pages
+{{object 32 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [13 0 R]
+
+>>
+endobj
+{{object 34 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [10 0 R]
+>>
+endobj
+% Document JS Action
+{{object 40 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS 41 0 R
+>>
+endobj
+% JS program to exexute
+{{object 41 0}} <<
+ {{streamlen}}
+>>
+stream
+var field_text = this.getField("Field_TextEdit");
+var field_combobox = this.getField("Field_ComboBox");
+field_combobox.setFocus();
+this.__defineGetter__("filesize", function new_getter(){
+ field_text.setFocus();
+ field_combobox.borderStyle="dashed";
+ field_combobox.setFocus();
+ });
+endstream
+endobj
+% OpenAction action
+{{object 20 0}} <<
+ /S /JavaScript
+ /JS 21 0 R
+>>
+endobj
+% JS program to exexute
+{{object 21 0}} <<
+ {{streamlen}}
+>>
+stream
+var t = this.filesize;
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom Sepez <tsepez@chromium.org>
Date: Thu, 18 May 2023 18:37:17 +0000
Subject: Observe widget across SetOptionSelection() calls.
Call may re-enter JavaScript.
Bug: chromium:1444581
Change-Id: Id7a2f17b3b81f822ca8f4496ac08c19b7794c48a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107394
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
(cherry picked from commit a9ff918a86d700c3bdf9b5820faed35490c0cd25)
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107735
Auto-Submit: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index ea119ec093c748c6c8bfb7b3c31b4ae97f959908..31134bb1e576003cc377eb90a61898f8097f080c 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -116,11 +116,18 @@ void CFFL_ListBox::SaveData(const CPDFSDK_PageView* pPageView) {
}
if (m_pWidget->GetFieldFlags() & pdfium::form_flags::kChoiceMultiSelect) {
for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) {
- if (pListBox->IsItemSelected(i))
+ if (pListBox->IsItemSelected(i)) {
m_pWidget->SetOptionSelection(i);
+ if (!observed_box) {
+ return;
+ }
+ }
}
} else {
m_pWidget->SetOptionSelection(pListBox->GetCurSel());
+ if (!observed_box) {
+ return;
+ }
}
ObservedPtr<CPDFSDK_Widget> observed_widget(m_pWidget);
ObservedPtr<CFFL_ListBox> observed_this(this);

View File

@@ -9,3 +9,8 @@ fix_disable_implies_dcheck_for_node_stream_array_buffers.patch
force_cppheapcreateparams_to_be_noncopyable.patch
chore_allow_customizing_microtask_policy_per_context.patch
store_the_thread_stack_start_in_tls.patch
cherry-pick-3b0607d14060.patch
cherry-pick-9c6dfc733fce.patch
cherry-pick-73af1a19a901.patch
cherry-pick-0035a4a8dac2.patch
cherry-pick-2e76270cf65e.patch

View File

@@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Fri, 2 Jun 2023 14:49:41 +0200
Subject: Merged: [ic] Fix store handler selection for arguments objects
Drive-by: fix printing of handlers in --trace-feedback-updates mode.
Bug: chromium:1450481
(cherry picked from commit e144f3b71e64e01d6ffd247eb15ca1ff56f6287b)
Change-Id: I0d2c90d92aa006ab37a653822f3a514343a5bac4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4583221
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#37}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index 213f6f8ea0af4157c66c9e2ac66ab4c8687dfd8d..9405e0dbfb107448e122b46e70e0eaf340102190 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -1338,12 +1338,18 @@ void FeedbackNexus::Print(std::ostream& os) {
case FeedbackSlotKind::kSetKeyedStrict: {
os << InlineCacheState2String(ic_state());
if (ic_state() == InlineCacheState::MONOMORPHIC) {
- os << "\n " << Brief(GetFeedback()) << ": ";
- Object handler = GetFeedbackExtra().GetHeapObjectOrSmi();
- if (handler.IsWeakFixedArray()) {
- handler = WeakFixedArray::cast(handler).Get(0).GetHeapObjectOrSmi();
+ HeapObject feedback = GetFeedback().GetHeapObject();
+ HeapObject feedback_extra = GetFeedbackExtra().GetHeapObject();
+ if (feedback.IsName()) {
+ os << " with name " << Brief(feedback);
+ WeakFixedArray array = WeakFixedArray::cast(feedback_extra);
+ os << "\n " << Brief(array.Get(0)) << ": ";
+ Object handler = array.Get(1).GetHeapObjectOrSmi();
+ StoreHandler::PrintHandler(handler, os);
+ } else {
+ os << "\n " << Brief(feedback) << ": ";
+ StoreHandler::PrintHandler(feedback_extra, os);
}
- StoreHandler::PrintHandler(handler, os);
} else if (ic_state() == InlineCacheState::POLYMORPHIC) {
HeapObject feedback = GetFeedback().GetHeapObject();
WeakFixedArray array;
diff --git a/src/ic/handler-configuration.cc b/src/ic/handler-configuration.cc
index 51c25e40dc0162d9b6bced1db712e42dae02d466..0eed4713837d7e683df8c021de10d0d0f341f1a8 100644
--- a/src/ic/handler-configuration.cc
+++ b/src/ic/handler-configuration.cc
@@ -593,8 +593,11 @@ void StoreHandler::PrintHandler(Object handler, std::ostream& os) {
os << ", validity cell = ";
store_handler.validity_cell().ShortPrint(os);
os << ")" << std::endl;
+ } else if (handler.IsMap()) {
+ os << "StoreHandler(field transition to " << Brief(handler) << ")"
+ << std::endl;
} else {
- os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")";
+ os << "StoreHandler(<unexpected>)(" << Brief(handler) << ")" << std::endl;
}
}
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 8754a849636826a0eef18381773b7a2a8a0a4edc..51371baa30b6465e46a51f540ffaba98251ebf67 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -2308,10 +2308,18 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
receiver_map->has_sealed_elements() ||
receiver_map->has_nonextensible_elements() ||
receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
+ // TODO(jgruber): Update counter name.
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
- code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
- if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
- return code;
+ if (receiver_map->IsJSArgumentsObjectMap() &&
+ receiver_map->has_fast_packed_elements()) {
+ // Allow fast behaviour for in-bounds stores while making it miss and
+ // properly handle the out of bounds store case.
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), STANDARD_STORE);
+ } else {
+ code = StoreHandler::StoreFastElementBuiltin(isolate(), store_mode);
+ if (receiver_map->has_typed_array_or_rab_gsab_typed_array_elements()) {
+ return code;
+ }
}
} else if (IsStoreInArrayLiteralIC()) {
// TODO(jgruber): Update counter name.
@@ -2322,7 +2330,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
DCHECK(DICTIONARY_ELEMENTS == receiver_map->elements_kind() ||
receiver_map->has_frozen_elements());
- code = StoreHandler::StoreSlow(isolate(), store_mode);
+ return StoreHandler::StoreSlow(isolate(), store_mode);
}
if (IsAnyDefineOwn() || IsStoreInArrayLiteralIC()) return code;
diff --git a/src/objects/map-inl.h b/src/objects/map-inl.h
index 2c42cf2ee635896b1f5c631be5fbfa5dc167f763..077d7fb0562d731a1918d671a544fd0040759bf1 100644
--- a/src/objects/map-inl.h
+++ b/src/objects/map-inl.h
@@ -613,6 +613,10 @@ bool Map::has_fast_elements() const {
return IsFastElementsKind(elements_kind());
}
+bool Map::has_fast_packed_elements() const {
+ return IsFastPackedElementsKind(elements_kind());
+}
+
bool Map::has_sloppy_arguments_elements() const {
return IsSloppyArgumentsElementsKind(elements_kind());
}
diff --git a/src/objects/map.h b/src/objects/map.h
index bdc10ee2baa7b2ba3ffa8e1292eace4376f84a88..2e61b1eb97c701a5646bbadb6bbbe7f0c06e0351 100644
--- a/src/objects/map.h
+++ b/src/objects/map.h
@@ -426,6 +426,7 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
inline bool has_fast_smi_or_object_elements() const;
inline bool has_fast_double_elements() const;
inline bool has_fast_elements() const;
+ inline bool has_fast_packed_elements() const;
inline bool has_sloppy_arguments_elements() const;
inline bool has_fast_sloppy_arguments_elements() const;
inline bool has_fast_string_wrapper_elements() const;

View File

@@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Mon, 5 Jun 2023 16:05:52 -0700
Subject: Merged: Check for encoding when appending in string builder
Fixed: chromium:1450114
(cherry picked from commit a7e2bef27b72f187a7dcdf95714df686f56d9e0b)
Change-Id: I5838383b6b12d137e84c8a36863ef88000e85c76
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4604652
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#41}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/strings/string-builder.cc b/src/strings/string-builder.cc
index f6871d9e6aa33942ec595e3076f689c2008989d7..30540b6a32a006fa4417d612a1243f18f59d3c2e 100644
--- a/src/strings/string-builder.cc
+++ b/src/strings/string-builder.cc
@@ -317,12 +317,21 @@ bool IncrementalStringBuilder::CanAppendByCopy(Handle<String> string) {
void IncrementalStringBuilder::AppendStringByCopy(Handle<String> string) {
DCHECK(CanAppendByCopy(string));
- Handle<SeqOneByteString> part =
- Handle<SeqOneByteString>::cast(current_part());
{
DisallowGarbageCollection no_gc;
- String::WriteToFlat(*string, part->GetChars(no_gc) + current_index_, 0,
- string->length());
+ if (encoding_ == String::ONE_BYTE_ENCODING) {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqOneByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ } else {
+ String::WriteToFlat(
+ *string,
+ Handle<SeqTwoByteString>::cast(current_part())->GetChars(no_gc) +
+ current_index_,
+ 0, string->length());
+ }
}
current_index_ += string->length();
DCHECK(current_index_ <= part_length_);

View File

@@ -0,0 +1,186 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Wed, 17 May 2023 13:47:36 +0200
Subject: Merged: [runtime] Remove redundant calls to GetPropertyAttributes
... when defining properties in favour of CheckIfCanDefine.
Drive-by: move JSReceiver::CheckIfCanDefine to
JSObject::CheckIfCanDefineAsConfigurable and fix handling of
absent properties.
Bug: chromium:1443452
(cherry picked from commit e98baa3526426c0219bb0474028ca301b8bd0677)
Change-Id: Ia1fd617778be608accee99dcee37f7d1ce3460b8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545762
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#22}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 55aa9d2c989f3fc846f0523ce5bd6a1483d448fa..8754a849636826a0eef18381773b7a2a8a0a4edc 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1815,14 +1815,14 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
// been thrown if the private field already exists in the object.
if (IsAnyDefineOwn() && !name->IsPrivateName() && !object->IsJSProxy() &&
!Handle<JSObject>::cast(object)->HasNamedInterceptor()) {
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
isolate(), &it, value, Nothing<ShouldThrow>());
MAYBE_RETURN_NULL(can_define);
if (!can_define.FromJust()) {
return isolate()->factory()->undefined_value();
}
- // Restart the lookup iterator updated by CheckIfCanDefine() for
- // UpdateCaches() to handle access checks.
+ // Restart the lookup iterator updated by CheckIfCanDefineAsConfigurable()
+ // for UpdateCaches() to handle access checks.
if (use_ic && object->IsAccessCheckNeeded()) {
it.Restart();
}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 8e11fb4ac241f1995aab7b4722822a352654108e..a53d487479d2c9e1de7da2bd63769e8e429f1890 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -249,27 +249,6 @@ Maybe<bool> JSReceiver::CheckPrivateNameStore(LookupIterator* it,
return Just(true);
}
-// static
-Maybe<bool> JSReceiver::CheckIfCanDefine(Isolate* isolate, LookupIterator* it,
- Handle<Object> value,
- Maybe<ShouldThrow> should_throw) {
- if (it->IsFound()) {
- Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
- MAYBE_RETURN(attributes, Nothing<bool>());
- if ((attributes.FromJust() & DONT_DELETE) != 0) {
- RETURN_FAILURE(
- isolate, GetShouldThrow(isolate, should_throw),
- NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
- }
- } else if (!JSObject::IsExtensible(
- isolate, Handle<JSObject>::cast(it->GetReceiver()))) {
- RETURN_FAILURE(
- isolate, GetShouldThrow(isolate, should_throw),
- NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
- }
- return Just(true);
-}
-
namespace {
bool HasExcludedProperty(
@@ -3679,7 +3658,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
if (semantics == EnforceDefineSemantics::kDefine) {
it->Restart();
- Maybe<bool> can_define = JSReceiver::CheckIfCanDefine(
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
it->isolate(), it, value, should_throw);
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
@@ -4108,16 +4087,15 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
Handle<Object> value,
Maybe<ShouldThrow> should_throw) {
DCHECK(it->GetReceiver()->IsJSObject());
- MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
Isolate* isolate = it->isolate();
- Maybe<bool> can_define =
- JSReceiver::CheckIfCanDefine(isolate, it, value, should_throw);
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
+ isolate, it, value, should_throw);
if (can_define.IsNothing() || !can_define.FromJust()) {
return can_define;
}
- RETURN_ON_EXCEPTION_VALUE(it->isolate(),
+ RETURN_ON_EXCEPTION_VALUE(isolate,
DefineOwnPropertyIgnoreAttributes(it, value, NONE),
Nothing<bool>());
@@ -4753,19 +4731,43 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
return it.factory()->undefined_value();
}
- CHECK(GetPropertyAttributes(&it).IsJust());
-
- // ES5 forbids turning a property into an accessor if it's not
- // configurable. See 8.6.1 (Table 5).
- if (it.IsFound() && !it.IsConfigurable()) {
- return it.factory()->undefined_value();
- }
+ Maybe<bool> can_define = JSObject::CheckIfCanDefineAsConfigurable(
+ isolate, &it, info, Nothing<ShouldThrow>());
+ MAYBE_RETURN_NULL(can_define);
+ if (!can_define.FromJust()) return it.factory()->undefined_value();
it.TransitionToAccessorPair(info, attributes);
return object;
}
+// static
+Maybe<bool> JSObject::CheckIfCanDefineAsConfigurable(
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
+ Maybe<ShouldThrow> should_throw) {
+ DCHECK(it->GetReceiver()->IsJSObject());
+ if (it->IsFound()) {
+ Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
+ MAYBE_RETURN(attributes, Nothing<bool>());
+ if (attributes.FromJust() != ABSENT) {
+ if ((attributes.FromJust() & DONT_DELETE) != 0) {
+ RETURN_FAILURE(
+ isolate, GetShouldThrow(isolate, should_throw),
+ NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
+ }
+ return Just(true);
+ }
+ // Property does not exist, check object extensibility.
+ }
+ if (!JSObject::IsExtensible(isolate,
+ Handle<JSObject>::cast(it->GetReceiver()))) {
+ RETURN_FAILURE(
+ isolate, GetShouldThrow(isolate, should_throw),
+ NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
+ }
+ return Just(true);
+}
+
Object JSObject::SlowReverseLookup(Object value) {
if (HasFastProperties()) {
DescriptorArray descs = map().instance_descriptors();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index db154b56e2c5bc157345afed8d1a1fad35d56eae..dc1745a753a19c37320fd3a483d17b29c311793c 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -167,12 +167,6 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
V8_WARN_UNUSED_RESULT static Maybe<bool> CheckPrivateNameStore(
LookupIterator* it, bool is_define);
- // Check if a data property can be created on the object. It will fail with
- // an error when it cannot.
- V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefine(
- Isolate* isolate, LookupIterator* it, Handle<Object> value,
- Maybe<ShouldThrow> should_throw);
-
// ES6 7.3.4 (when passed kDontThrow)
V8_WARN_UNUSED_RESULT static Maybe<bool> CreateDataProperty(
Isolate* isolate, Handle<JSReceiver> object, Handle<Name> key,
@@ -550,6 +544,12 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> info,
PropertyAttributes attributes);
+ // Check if a data property can be created on the object. It will fail with
+ // an error when it cannot.
+ V8_WARN_UNUSED_RESULT static Maybe<bool> CheckIfCanDefineAsConfigurable(
+ Isolate* isolate, LookupIterator* it, Handle<Object> value,
+ Maybe<ShouldThrow> should_throw);
+
// The result must be checked first for exceptions. If there's no exception,
// the output parameter |done| indicates whether the interceptor has a result
// or not.

View File

@@ -0,0 +1,257 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Thu, 1 Jun 2023 10:59:39 +0200
Subject: Merged: [lookup] Robustify LookupIterator against own lookups
... on non-JSReceiver objects.
Bug: chromium:1447430
(cherry picked from commit 515f187ba067ee4a99fdf5198cca2c97abd342fd)
Change-Id: Ib9382d90ce19d6b55ee0b236dd299ded03ade04d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4575069
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#35}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
index 00c95e013c17ae77a630431c74f9b44cdf49f884..8b5717021beb806d2572e43b20f2b06c4d3f035e 100644
--- a/src/objects/lookup-inl.h
+++ b/src/objects/lookup-inl.h
@@ -190,7 +190,7 @@ Handle<Name> PropertyKey::GetName(Isolate* isolate) {
}
Handle<Name> LookupIterator::name() const {
- DCHECK(!IsElement(*holder_));
+ DCHECK_IMPLIES(!holder_.is_null(), !IsElement(*holder_));
return name_;
}
@@ -285,6 +285,7 @@ void LookupIterator::UpdateProtector() {
}
InternalIndex LookupIterator::descriptor_number() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(has_property_);
DCHECK(holder_->HasFastProperties(isolate_));
@@ -292,6 +293,7 @@ InternalIndex LookupIterator::descriptor_number() const {
}
InternalIndex LookupIterator::dictionary_entry() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(has_property_);
DCHECK(!holder_->HasFastProperties(isolate_));
@@ -306,13 +308,14 @@ LookupIterator::Configuration LookupIterator::ComputeConfiguration(
}
// static
-Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
- Handle<Object> lookup_start_object,
- size_t index) {
+MaybeHandle<JSReceiver> LookupIterator::GetRoot(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration) {
if (lookup_start_object->IsJSReceiver(isolate)) {
return Handle<JSReceiver>::cast(lookup_start_object);
}
- return GetRootForNonJSReceiver(isolate, lookup_start_object, index);
+ return GetRootForNonJSReceiver(isolate, lookup_start_object, index,
+ configuration);
}
template <class T>
diff --git a/src/objects/lookup.cc b/src/objects/lookup.cc
index e3bf4794e88e7c3ae5d4028b16eeadf282d9c410..149149beba8d6e62dd5d821f7017b18e08445bd8 100644
--- a/src/objects/lookup.cc
+++ b/src/objects/lookup.cc
@@ -42,27 +42,20 @@ PropertyKey::PropertyKey(Isolate* isolate, Handle<Object> key, bool* success) {
}
}
-LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
- Handle<Name> name, Handle<Map> transition_map,
- PropertyDetails details, bool has_property)
- : configuration_(DEFAULT),
- state_(TRANSITION),
- has_property_(has_property),
- interceptor_state_(InterceptorState::kUninitialized),
- property_details_(details),
- isolate_(isolate),
- name_(name),
- transition_(transition_map),
- receiver_(receiver),
- lookup_start_object_(receiver),
- index_(kInvalidIndex) {
- holder_ = GetRoot(isolate, lookup_start_object_);
-}
-
template <bool is_element>
void LookupIterator::Start() {
// GetRoot might allocate if lookup_start_object_ is a string.
- holder_ = GetRoot(isolate_, lookup_start_object_, index_);
+ MaybeHandle<JSReceiver> maybe_holder =
+ GetRoot(isolate_, lookup_start_object_, index_, configuration_);
+ if (!maybe_holder.ToHandle(&holder_)) {
+ // This is an attempt to perform an own property lookup on a non-JSReceiver
+ // that doesn't have any properties.
+ DCHECK(!lookup_start_object_->IsJSReceiver());
+ DCHECK(!check_prototype_chain());
+ has_property_ = false;
+ state_ = NOT_FOUND;
+ return;
+ }
{
DisallowGarbageCollection no_gc;
@@ -135,19 +128,27 @@ template void LookupIterator::RestartInternal<true>(InterceptorState);
template void LookupIterator::RestartInternal<false>(InterceptorState);
// static
-Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
- Isolate* isolate, Handle<Object> lookup_start_object, size_t index) {
- // Strings are the only objects with properties (only elements) directly on
- // the wrapper. Hence we can skip generating the wrapper for all other cases.
- if (lookup_start_object->IsString(isolate) &&
- index <
- static_cast<size_t>(String::cast(*lookup_start_object).length())) {
- // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the native
- // context, ensuring that we don't leak it into JS?
- Handle<JSFunction> constructor = isolate->string_function();
- Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
- Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
- return result;
+MaybeHandle<JSReceiver> LookupIterator::GetRootForNonJSReceiver(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration) {
+ // Strings are the only non-JSReceiver objects with properties (only elements
+ // and 'length') directly on the wrapper. Hence we can skip generating
+ // the wrapper for all other cases.
+ bool own_property_lookup = (configuration & kPrototypeChain) == 0;
+ if (lookup_start_object->IsString(isolate)) {
+ if (own_property_lookup ||
+ index <
+ static_cast<size_t>(String::cast(*lookup_start_object).length())) {
+ // TODO(verwaest): Speed this up. Perhaps use a cached wrapper on the
+ // native context, ensuring that we don't leak it into JS?
+ Handle<JSFunction> constructor = isolate->string_function();
+ Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
+ Handle<JSPrimitiveWrapper>::cast(result)->set_value(*lookup_start_object);
+ return result;
+ }
+ } else if (own_property_lookup) {
+ // Signal that the lookup will not find anything.
+ return {};
}
Handle<HeapObject> root(
lookup_start_object->GetPrototypeChainRootMap(isolate).prototype(isolate),
@@ -918,6 +919,7 @@ Handle<Object> LookupIterator::FetchValue(
}
bool LookupIterator::CanStayConst(Object value) const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
@@ -951,6 +953,7 @@ bool LookupIterator::CanStayConst(Object value) const {
}
bool LookupIterator::DictCanStayConst(Object value) const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(!holder_->HasFastProperties(isolate_));
DCHECK(!holder_->IsJSGlobalObject());
@@ -997,6 +1000,7 @@ int LookupIterator::GetAccessorIndex() const {
FieldIndex LookupIterator::GetFieldIndex() const {
DCHECK(has_property_);
+ DCHECK(!holder_.is_null());
DCHECK(holder_->HasFastProperties(isolate_));
DCHECK_EQ(PropertyLocation::kField, property_details_.location());
DCHECK(!IsElement(*holder_));
@@ -1004,6 +1008,7 @@ FieldIndex LookupIterator::GetFieldIndex() const {
}
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
return handle(holder->global_dictionary(isolate_, kAcquireLoad)
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
index 06ed50e97b14e29c7328d2612151b1788c85c84f..5d2d926b7e3dcecf8529f7d1c1e919033d9faa7f 100644
--- a/src/objects/lookup.h
+++ b/src/objects/lookup.h
@@ -222,11 +222,6 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Object> lookup_start_object,
Configuration configuration);
- // For |ForTransitionHandler|.
- LookupIterator(Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
- Handle<Map> transition_map, PropertyDetails details,
- bool has_property);
-
static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
@@ -286,12 +281,12 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Configuration configuration,
Handle<Name> name);
- static Handle<JSReceiver> GetRootForNonJSReceiver(
- Isolate* isolate, Handle<Object> lookup_start_object,
- size_t index = kInvalidIndex);
- static inline Handle<JSReceiver> GetRoot(Isolate* isolate,
- Handle<Object> lookup_start_object,
- size_t index = kInvalidIndex);
+ static MaybeHandle<JSReceiver> GetRootForNonJSReceiver(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration);
+ static inline MaybeHandle<JSReceiver> GetRoot(
+ Isolate* isolate, Handle<Object> lookup_start_object, size_t index,
+ Configuration configuration);
State NotFound(JSReceiver const holder) const;
diff --git a/test/mjsunit/regress/regress-crbug-1447430.js b/test/mjsunit/regress/regress-crbug-1447430.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7bb3e72e3af1b9f8c2fa82faeeb2d813fe6ab3c
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1447430.js
@@ -0,0 +1,34 @@
+// Copyright 2023 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var s = %CreatePrivateSymbol('x');
+
+(function TestSmi() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ (1).__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f(42, s), undefined);
+}());
+
+(function TestString() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ ('xyz').__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f('abc', s), undefined);
+}());
+
+(function TestSymbol() {
+ function f(o, p) {
+ o[p] = 153;
+ }
+ Symbol('xyz').__proto__[s] = 42;
+ %PrepareFunctionForOptimization(f);
+ assertEquals(f(Symbol('abc'), s), undefined);
+}());

View File

@@ -0,0 +1,150 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Tue, 16 May 2023 16:01:49 +0200
Subject: Merged: [runtime] Fix handling of interceptors
Drive-by: simplify creation of LookupIterator copies.
Bug: chromium:1440695
(cherry picked from commit d125c7329f6e22af4523de3c55de3a22f168acc9)
Change-Id: I58416531b9af3456f53264566ec1eb7457328f94
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4545763
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.4@{#23}
Cr-Branched-From: 8a8a1e7086dacc426965d3875914efa66663c431-refs/heads/11.4.183@{#1}
Cr-Branched-From: 5483d8e816e0bbce865cbbc3fa0ab357e6330bab-refs/heads/main@{#87241}
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index a53d487479d2c9e1de7da2bd63769e8e429f1890..9bc37cc246fc89d2856b6c8a7800cad930e28dc7 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3669,10 +3669,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
// own property without the interceptor.
Isolate* isolate = it->isolate();
Handle<Object> receiver = it->GetReceiver();
- LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
- LookupIterator own_lookup =
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
- : LookupIterator(isolate, receiver, it->name(), c);
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
+ LookupIterator::OWN_SKIP_INTERCEPTOR);
return JSObject::DefineOwnPropertyIgnoreAttributes(
&own_lookup, value, attributes, should_throw, handling, semantics,
store_origin);
diff --git a/src/objects/lookup-inl.h b/src/objects/lookup-inl.h
index d34f710147ea799bcc8a89b4b58e176918071bf6..00c95e013c17ae77a630431c74f9b44cdf49f884 100644
--- a/src/objects/lookup-inl.h
+++ b/src/objects/lookup-inl.h
@@ -130,6 +130,29 @@ PropertyKey::PropertyKey(Isolate* isolate, double index) {
#endif
}
+PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name, size_t index)
+ : name_(name), index_(index) {
+ DCHECK_IMPLIES(index_ == LookupIterator::kInvalidIndex, !name_.is_null());
+#if V8_TARGET_ARCH_32_BIT
+ DCHECK_IMPLIES(index_ != LookupIterator::kInvalidIndex,
+ index_ <= JSObject::kMaxElementIndex);
+#endif
+#if DEBUG
+ if (index_ != LookupIterator::kInvalidIndex && !name_.is_null()) {
+ // If both valid index and name are given then the name is a string
+ // representation of the same index.
+ size_t integer_index;
+ CHECK(name_->AsIntegerIndex(&integer_index));
+ CHECK_EQ(index_, integer_index);
+ } else if (index_ == LookupIterator::kInvalidIndex) {
+ // If only name is given it must not be a string representing an integer
+ // index.
+ size_t integer_index;
+ CHECK(!name_->AsIntegerIndex(&integer_index));
+ }
+#endif
+}
+
PropertyKey::PropertyKey(Isolate* isolate, Handle<Name> name) {
if (name->AsIntegerIndex(&index_)) {
name_ = name;
@@ -179,6 +202,10 @@ Handle<Name> LookupIterator::GetName() {
return name_;
}
+PropertyKey LookupIterator::GetKey() const {
+ return PropertyKey(isolate_, name_, index_);
+}
+
bool LookupIterator::IsElement(JSReceiver object) const {
return index_ <= JSObject::kMaxElementIndex ||
(index_ != kInvalidIndex &&
diff --git a/src/objects/lookup.h b/src/objects/lookup.h
index 9adee79b3028c53e6481a07316d74aed616f01bd..06ed50e97b14e29c7328d2612151b1788c85c84f 100644
--- a/src/objects/lookup.h
+++ b/src/objects/lookup.h
@@ -36,6 +36,11 @@ class PropertyKey {
inline Handle<Name> GetName(Isolate* isolate);
private:
+ friend LookupIterator;
+
+ // Shortcut for constructing PropertyKey from an active LookupIterator.
+ inline PropertyKey(Isolate* isolate, Handle<Name> name, size_t index);
+
Handle<Name> name_;
size_t index_;
};
@@ -108,6 +113,9 @@ class V8_EXPORT_PRIVATE LookupIterator final {
return static_cast<uint32_t>(index_);
}
+ // Helper method for creating a copy of of the iterator.
+ inline PropertyKey GetKey() const;
+
// Returns true if this LookupIterator has an index in the range
// [0, size_t::max).
bool IsElement() const { return index_ != kInvalidIndex; }
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 26a8d59b34e99ca110479b3f3211e298d1ecbcc4..0907a4b3444d10ce22c16de1a5ecbdb5f4b982af 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -2662,11 +2662,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
// Note, the callers rely on the fact that this code is redoing the full own
// lookup from scratch.
- LookupIterator::Configuration c = LookupIterator::OWN;
- LookupIterator own_lookup =
- it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c)
- : LookupIterator(isolate, receiver, it->name(), c);
-
+ LookupIterator own_lookup(isolate, receiver, it->GetKey(),
+ LookupIterator::OWN);
for (; own_lookup.IsFound(); own_lookup.Next()) {
switch (own_lookup.state()) {
case LookupIterator::ACCESS_CHECK:
@@ -2703,6 +2700,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
JSReceiver::GetOwnPropertyDescriptor(&own_lookup, &desc);
MAYBE_RETURN(owned, Nothing<bool>());
if (!owned.FromJust()) {
+ // |own_lookup| might become outdated at this point anyway.
+ own_lookup.Restart();
if (!CheckContextualStoreToJSGlobalObject(&own_lookup,
should_throw)) {
return Nothing<bool>();
diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc
index 635bf6a0b72f8d49591be333b1314846c9c47269..416f9bd1eb4c59160eb03031e6011ae02dcf021e 100644
--- a/test/unittests/api/interceptor-unittest.cc
+++ b/test/unittests/api/interceptor-unittest.cc
@@ -174,8 +174,10 @@ TEST_F(InterceptorLoggingTest, DispatchTest) {
EXPECT_EQ(Run("obj.foo"), "named getter");
EXPECT_EQ(Run("obj[42]"), "indexed getter");
- EXPECT_EQ(Run("obj.foo = null"), "named setter, named descriptor");
- EXPECT_EQ(Run("obj[42] = null"), "indexed setter, indexed descriptor");
+ EXPECT_EQ(Run("obj.foo = null"),
+ "named setter, named descriptor, named query");
+ EXPECT_EQ(Run("obj[42] = null"),
+ "indexed setter, indexed descriptor, indexed query");
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
"named descriptor");

View File

@@ -1 +1,2 @@
fix_fallback_to_x11_capturer_on_wayland.patch
m114_move_transceiver_iteration_loop_over_to_the_signaling_thread.patch

View File

@@ -0,0 +1,126 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tommi <tommi@webrtc.org>
Date: Thu, 1 Jun 2023 16:08:52 +0200
Subject: Move transceiver iteration loop over to the signaling thread.
This is required for ReportTransportStats since iterating over the
transceiver list from the network thread is not safe.
(cherry picked from commit dba22d31909298161318e00d43a80cdb0abc940f)
No-Try: true
Bug: chromium:1446274, webrtc:12692
Change-Id: I7c514df9f029112c4b1da85826af91217850fb26
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307340
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Original-Commit-Position: refs/heads/main@{#40197}
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308001
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/branch-heads/5735@{#3}
Cr-Branched-From: df7df199abd619e75b9f1d9a7e12fc3f3f748775-refs/heads/main@{#39949}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 88b99bb515325b9c616b7d06495c7a9c924133b2..5701504e7a6ebd96bd5cafdbe37de4a510f6a436 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -728,9 +728,6 @@ JsepTransportController* PeerConnection::InitializeTransportController_n(
transport_controller_->SubscribeIceConnectionState(
[this](cricket::IceConnectionState s) {
RTC_DCHECK_RUN_ON(network_thread());
- if (s == cricket::kIceConnectionConnected) {
- ReportTransportStats();
- }
signaling_thread()->PostTask(
SafeTask(signaling_thread_safety_.flag(), [this, s]() {
RTC_DCHECK_RUN_ON(signaling_thread());
@@ -2415,6 +2412,20 @@ void PeerConnection::OnTransportControllerConnectionState(
case cricket::kIceConnectionConnected:
RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
"all transports are writable.";
+ {
+ std::vector<RtpTransceiverProxyRefPtr> transceivers;
+ if (ConfiguredForMedia()) {
+ transceivers = rtp_manager()->transceivers()->List();
+ }
+
+ network_thread()->PostTask(
+ SafeTask(network_thread_safety_,
+ [this, transceivers = std::move(transceivers)] {
+ RTC_DCHECK_RUN_ON(network_thread());
+ ReportTransportStats(std::move(transceivers));
+ }));
+ }
+
SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
break;
@@ -2762,20 +2773,18 @@ void PeerConnection::OnTransportControllerGatheringState(
}
// Runs on network_thread().
-void PeerConnection::ReportTransportStats() {
+void PeerConnection::ReportTransportStats(
+ std::vector<RtpTransceiverProxyRefPtr> transceivers) {
TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
std::map<std::string, std::set<cricket::MediaType>>
media_types_by_transport_name;
- if (ConfiguredForMedia()) {
- for (const auto& transceiver :
- rtp_manager()->transceivers()->UnsafeList()) {
- if (transceiver->internal()->channel()) {
- std::string transport_name(
- transceiver->internal()->channel()->transport_name());
- media_types_by_transport_name[transport_name].insert(
- transceiver->media_type());
- }
+ for (const auto& transceiver : transceivers) {
+ if (transceiver->internal()->channel()) {
+ std::string transport_name(
+ transceiver->internal()->channel()->transport_name());
+ media_types_by_transport_name[transport_name].insert(
+ transceiver->media_type());
}
}
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 850142b9584a9f2e5b29b337b2bcd433d4b0224d..69b2ca7925eceb636aa4d22b9397cb25a7637051 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -569,7 +569,8 @@ class PeerConnection : public PeerConnectionInternal,
// Invoked when TransportController connection completion is signaled.
// Reports stats for all transports in use.
- void ReportTransportStats() RTC_RUN_ON(network_thread());
+ void ReportTransportStats(std::vector<RtpTransceiverProxyRefPtr> transceivers)
+ RTC_RUN_ON(network_thread());
// Gather the usage of IPv4/IPv6 as best connection.
static void ReportBestConnectionState(const cricket::TransportStats& stats);
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 1d1bec3e93e0e87bb0b1da13c13ed11712ad0480..c373e2f643b33dea4e619e38dfc8d1007f2cedad 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -1831,6 +1831,10 @@ TEST_P(PeerConnectionIntegrationTest,
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.CandidatePairType_UDP",
webrtc::kIceCandidatePairHostNameHostName));
@@ -1959,6 +1963,10 @@ TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) {
EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected,
callee()->ice_connection_state(), kDefaultTimeout);
+ // Part of reporting the stats will occur on the network thread, so flush it
+ // before checking NumEvents.
+ SendTask(network_thread(), [] {});
+
// TODO(bugs.webrtc.org/9456): Fix it.
const int num_best_ipv4 = webrtc::metrics::NumEvents(
"WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4);

View File

@@ -30,6 +30,32 @@ const IGNORELIST = new Set([
const IS_WINDOWS = process.platform === 'win32';
const CPPLINT_FILTERS = [
// from presubmit_canned_checks.py OFF_BY_DEFAULT_LINT_FILTERS
'-build/include',
'-build/include_order',
'-build/namespaces',
'-readability/casting',
'-runtime/int',
'-whitespace/braces',
// from presubmit_canned_checks.py OFF_UNLESS_MANUALLY_ENABLED_LINT_FILTERS
'-build/c++11',
'-build/header_guard',
'-readability/todo',
'-runtime/references',
'-whitespace/braces',
'-whitespace/comma',
'-whitespace/end_of_line',
'-whitespace/forcolon',
'-whitespace/indent',
'-whitespace/line_length',
'-whitespace/newline',
'-whitespace/operators',
'-whitespace/parens',
'-whitespace/semicolon',
'-whitespace/tab'
];
function spawnAndCheckExitCode (cmd, args, opts) {
opts = { stdio: 'inherit', ...opts };
const { error, status, signal } = childProcess.spawnSync(cmd, args, opts);
@@ -78,7 +104,7 @@ const LINTERS = [{
const clangFormatFlags = opts.fix ? ['--fix'] : [];
for (const chunk of chunkFilenames(filenames)) {
spawnAndCheckExitCode('python3', ['script/run-clang-format.py', ...clangFormatFlags, ...chunk]);
cpplint(chunk);
cpplint([`--filter=${CPPLINT_FILTERS.join(',')}`, ...chunk]);
}
}
}, {
@@ -88,13 +114,7 @@ const LINTERS = [{
run: (opts, filenames) => {
const clangFormatFlags = opts.fix ? ['--fix'] : [];
spawnAndCheckExitCode('python3', ['script/run-clang-format.py', '-r', ...clangFormatFlags, ...filenames]);
const filter = [
'-readability/braces',
'-readability/casting',
'-whitespace/braces',
'-whitespace/indent',
'-whitespace/parens'
];
const filter = [...CPPLINT_FILTERS, '-readability/braces'];
cpplint(['--extensions=mm,h', `--filter=${filter.join(',')}`, ...filenames]);
}
}, {

View File

@@ -77,7 +77,7 @@ async function validateReleaseAssets (release, validatingRelease) {
} else {
await verifyShasumsForRemoteFiles(downloadUrls)
.catch(err => {
console.log(`${fail} error verifyingShasums`, err);
console.error(`${fail} error verifyingShasums`, err);
});
}
const azRemoteFiles = azRemoteFilesForVersion(release.tag_name);
@@ -90,7 +90,7 @@ function check (condition, statement, exitIfFail = false) {
console.log(`${pass} ${statement}`);
} else {
failureCount++;
console.log(`${fail} ${statement}`);
console.error(`${fail} ${statement}`);
if (exitIfFail) process.exit(1);
}
}
@@ -212,7 +212,7 @@ function runScript (scriptName, scriptArgs, cwd) {
try {
return execSync(scriptCommand, scriptOptions);
} catch (err) {
console.log(`${fail} Error running ${scriptName}`, err);
console.error(`${fail} Error running ${scriptName}`, err);
process.exit(1);
}
}
@@ -266,7 +266,8 @@ async function createReleaseShasums (release) {
repo: targetRepo,
asset_id: existingAssets[0].id
}).catch(err => {
console.log(`${fail} Error deleting ${fileName} on GitHub:`, err);
console.error(`${fail} Error deleting ${fileName} on GitHub:`, err);
process.exit(1);
});
}
console.log(`Creating and uploading the release ${fileName}.`);
@@ -292,7 +293,7 @@ async function uploadShasumFile (filePath, fileName, releaseId) {
data: fs.createReadStream(filePath),
name: fileName
}).catch(err => {
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err);
console.error(`${fail} Error uploading ${filePath} to GitHub:`, err);
process.exit(1);
});
}
@@ -301,13 +302,13 @@ function saveShaSumFile (checksums, fileName) {
return new Promise((resolve, reject) => {
temp.open(fileName, (err, info) => {
if (err) {
console.log(`${fail} Could not create ${fileName} file`);
console.error(`${fail} Could not create ${fileName} file`);
process.exit(1);
} else {
fs.writeFileSync(info.fd, checksums);
fs.close(info.fd, (err) => {
if (err) {
console.log(`${fail} Could close ${fileName} file`);
console.error(`${fail} Could close ${fileName} file`);
process.exit(1);
}
resolve(info.path);
@@ -333,7 +334,7 @@ async function publishRelease (release) {
draft: false,
make_latest: makeLatest ? 'true' : 'false'
}).catch(err => {
console.log(`${fail} Error publishing release:`, err);
console.error(`${fail} Error publishing release:`, err);
process.exit(1);
});
}
@@ -351,13 +352,17 @@ async function makeRelease (releaseToValidate) {
} else {
let draftRelease = await getDraftRelease();
uploadNodeShasums();
uploadIndexJson();
await createReleaseShasums(draftRelease);
// Fetch latest version of release before verifying
draftRelease = await getDraftRelease(pkgVersion, true);
await validateReleaseAssets(draftRelease);
// index.json goes live once uploaded so do these uploads as
// late as possible to reduce the chances it contains a release
// which fails to publish. It has to be done before the final
// publish to ensure there aren't published releases not contained
// in index.json, which causes other problems in downstream projects
uploadIndexJson();
await publishRelease(draftRelease);
console.log(`${pass} SUCCESS!!! Release has been published. Please run ` +
'"npm run publish-to-npm" to publish release to npm.');
@@ -403,7 +408,7 @@ async function verifyDraftGitHubReleaseAssets (release) {
return { url: response.headers.location, file: asset.name };
})).catch(err => {
console.log(`${fail} Error downloading files from GitHub`, err);
console.error(`${fail} Error downloading files from GitHub`, err);
process.exit(1);
});

View File

@@ -7,12 +7,12 @@
#include <map>
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/fixed_flat_set.h"
#include "base/feature_list.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -54,9 +54,13 @@ namespace {
// See https://nodejs.org/api/cli.html#cli_options
int SetNodeCliFlags() {
// Options that are unilaterally disallowed
const std::unordered_set<base::StringPiece, base::StringPieceHash>
disallowed = {"--openssl-config", "--use-bundled-ca", "--use-openssl-ca",
"--force-fips", "--enable-fips"};
static constexpr auto disallowed = base::MakeFixedFlatSet<base::StringPiece>({
"--enable-fips",
"--force-fips",
"--openssl-config",
"--use-bundled-ca",
"--use-openssl-ca",
});
const auto argv = base::CommandLine::ForCurrentProcess()->argv();
std::vector<std::string> args;
@@ -74,7 +78,7 @@ int SetNodeCliFlags() {
const auto& option = arg;
#endif
const auto stripped = base::StringPiece(option).substr(0, option.find('='));
if (disallowed.count(stripped) != 0) {
if (disallowed.contains(stripped)) {
LOG(ERROR) << "The Node.js cli flag " << stripped
<< " is not supported in Electron";
// Node.js returns 9 from ProcessGlobalArgs for any errors encountered

View File

@@ -10,6 +10,7 @@
#include <vector>
#include "base/command_line.h"
#include "base/containers/fixed_flat_map.h"
#include "base/containers/span.h"
#include "base/environment.h"
#include "base/files/file_path.h"
@@ -473,51 +474,38 @@ IconLoader::IconSize GetIconSizeByString(const std::string& size) {
}
// Return the path constant from string.
int GetPathConstant(const std::string& name) {
if (name == "appData")
return DIR_APP_DATA;
else if (name == "sessionData")
return DIR_SESSION_DATA;
else if (name == "userData")
return chrome::DIR_USER_DATA;
else if (name == "cache")
constexpr int GetPathConstant(base::StringPiece name) {
// clang-format off
constexpr auto Lookup = base::MakeFixedFlatMap<base::StringPiece, int>({
{"appData", DIR_APP_DATA},
#if BUILDFLAG(IS_POSIX)
return base::DIR_CACHE;
{"cache", base::DIR_CACHE},
#else
return base::DIR_ROAMING_APP_DATA;
{"cache", base::DIR_ROAMING_APP_DATA},
#endif
else if (name == "userCache")
return DIR_USER_CACHE;
else if (name == "logs")
return DIR_APP_LOGS;
else if (name == "crashDumps")
return DIR_CRASH_DUMPS;
else if (name == "home")
return base::DIR_HOME;
else if (name == "temp")
return base::DIR_TEMP;
else if (name == "userDesktop" || name == "desktop")
return base::DIR_USER_DESKTOP;
else if (name == "exe")
return base::FILE_EXE;
else if (name == "module")
return base::FILE_MODULE;
else if (name == "documents")
return chrome::DIR_USER_DOCUMENTS;
else if (name == "downloads")
return chrome::DIR_DEFAULT_DOWNLOADS;
else if (name == "music")
return chrome::DIR_USER_MUSIC;
else if (name == "pictures")
return chrome::DIR_USER_PICTURES;
else if (name == "videos")
return chrome::DIR_USER_VIDEOS;
{"crashDumps", DIR_CRASH_DUMPS},
{"desktop", base::DIR_USER_DESKTOP},
{"documents", chrome::DIR_USER_DOCUMENTS},
{"downloads", chrome::DIR_DEFAULT_DOWNLOADS},
{"exe", base::FILE_EXE},
{"home", base::DIR_HOME},
{"logs", DIR_APP_LOGS},
{"module", base::FILE_MODULE},
{"music", chrome::DIR_USER_MUSIC},
{"pictures", chrome::DIR_USER_PICTURES},
#if BUILDFLAG(IS_WIN)
else if (name == "recent")
return electron::DIR_RECENT;
{"recent", electron::DIR_RECENT},
#endif
else
return -1;
{"sessionData", DIR_SESSION_DATA},
{"temp", base::DIR_TEMP},
{"userCache", DIR_USER_CACHE},
{"userData", chrome::DIR_USER_DATA},
{"userDesktop", base::DIR_USER_DESKTOP},
{"videos", chrome::DIR_USER_VIDEOS},
});
// clang-format on
const auto* iter = Lookup.find(name);
return iter != Lookup.end() ? iter->second : -1;
}
bool NotificationCallbackWrapper(

View File

@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/task/single_thread_task_runner.h"
#include "electron/buildflags/buildflags.h"
#include "gin/dictionary.h"
@@ -708,8 +709,6 @@ void BaseWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
v8::Local<v8::Object> object;
if (value->IsObject() && value->ToObject(context).ToLocal(&object) &&
gin::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
menu_.Reset(isolate, menu.ToV8());
// We only want to update the menu if the menu has a non-zero item count,
// or we risk crashes.
if (menu->model()->GetItemCount() == 0) {
@@ -717,6 +716,8 @@ void BaseWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
} else {
window_->SetMenu(menu->model());
}
menu_.Reset(isolate, menu.ToV8());
} else if (value->IsNull()) {
RemoveMenu();
} else {
@@ -760,8 +761,7 @@ void BaseWindow::SetBrowserView(
}
void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = browser_views_.find(browser_view->ID());
if (iter == browser_views_.end()) {
if (!base::Contains(browser_views_, browser_view->ID())) {
// If we're reparenting a BrowserView, ensure that it's detached from
// its previous owner window.
BaseWindow* owner_window = browser_view->owner_window();

View File

@@ -134,6 +134,10 @@ void BrowserView::WebContentsDestroyed() {
Unpin();
}
void BrowserView::OnCloseContents() {
api_web_contents_ = nullptr;
}
// static
gin::Handle<BrowserView> BrowserView::New(gin_helper::ErrorThrower thrower,
gin::Arguments* args) {

View File

@@ -71,6 +71,9 @@ class BrowserView : public gin::Wrappable<BrowserView>,
// content::WebContentsObserver:
void WebContentsDestroyed() override;
// ExtendedWebContentsObserver:
void OnCloseContents() override;
private:
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);

View File

@@ -169,7 +169,7 @@ base::Time ParseTimeProperty(const absl::optional<double>& value) {
return base::Time::FromDoubleT(*value);
}
std::string InclusionStatusToString(net::CookieInclusionStatus status) {
base::StringPiece InclusionStatusToString(net::CookieInclusionStatus status) {
if (status.HasExclusionReason(net::CookieInclusionStatus::EXCLUDE_HTTP_ONLY))
return "Failed to create httponly cookie";
if (status.HasExclusionReason(

View File

@@ -62,8 +62,7 @@ GlobalShortcut::~GlobalShortcut() {
}
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
if (accelerator_callback_map_.find(accelerator) ==
accelerator_callback_map_.end()) {
if (!base::Contains(accelerator_callback_map_, accelerator)) {
// This should never occur, because if it does, GlobalShortcutListener
// notifies us with wrong accelerator.
NOTREACHED();

View File

@@ -6,6 +6,7 @@
#include <string>
#include "base/containers/contains.h"
#include "base/functional/callback_helpers.h"
#include "content/public/browser/device_service.h"
#include "gin/dictionary.h"
@@ -106,8 +107,8 @@ bool PowerSaveBlocker::Stop(int id) {
return success;
}
bool PowerSaveBlocker::IsStarted(int id) {
return wake_lock_types_.find(id) != wake_lock_types_.end();
bool PowerSaveBlocker::IsStarted(int id) const {
return base::Contains(wake_lock_types_, id);
}
// static

View File

@@ -37,7 +37,7 @@ class PowerSaveBlocker : public gin::Wrappable<PowerSaveBlocker> {
void UpdatePowerSaveBlocker();
int Start(device::mojom::WakeLockType type);
bool Stop(int id);
bool IsStarted(int id);
bool IsStarted(int id) const;
device::mojom::WakeLock* GetWakeLock();

View File

@@ -167,7 +167,7 @@ const char* const kBuiltinSchemes[] = {
};
// Convert error code to string.
std::string ErrorCodeToString(ProtocolError error) {
constexpr base::StringPiece ErrorCodeToString(ProtocolError error) {
switch (error) {
case ProtocolError::kRegistered:
return "The scheme has been registered";

View File

@@ -25,33 +25,36 @@ namespace electron::api {
namespace {
std::string MessageSourceToString(
constexpr base::StringPiece MessageSourceToString(
const blink::mojom::ConsoleMessageSource source) {
if (source == blink::mojom::ConsoleMessageSource::kXml)
return "xml";
if (source == blink::mojom::ConsoleMessageSource::kJavaScript)
return "javascript";
if (source == blink::mojom::ConsoleMessageSource::kNetwork)
return "network";
if (source == blink::mojom::ConsoleMessageSource::kConsoleApi)
return "console-api";
if (source == blink::mojom::ConsoleMessageSource::kStorage)
return "storage";
if (source == blink::mojom::ConsoleMessageSource::kRendering)
return "rendering";
if (source == blink::mojom::ConsoleMessageSource::kSecurity)
return "security";
if (source == blink::mojom::ConsoleMessageSource::kDeprecation)
return "deprecation";
if (source == blink::mojom::ConsoleMessageSource::kWorker)
return "worker";
if (source == blink::mojom::ConsoleMessageSource::kViolation)
return "violation";
if (source == blink::mojom::ConsoleMessageSource::kIntervention)
return "intervention";
if (source == blink::mojom::ConsoleMessageSource::kRecommendation)
return "recommendation";
return "other";
switch (source) {
case blink::mojom::ConsoleMessageSource::kXml:
return "xml";
case blink::mojom::ConsoleMessageSource::kJavaScript:
return "javascript";
case blink::mojom::ConsoleMessageSource::kNetwork:
return "network";
case blink::mojom::ConsoleMessageSource::kConsoleApi:
return "console-api";
case blink::mojom::ConsoleMessageSource::kStorage:
return "storage";
case blink::mojom::ConsoleMessageSource::kRendering:
return "rendering";
case blink::mojom::ConsoleMessageSource::kSecurity:
return "security";
case blink::mojom::ConsoleMessageSource::kDeprecation:
return "deprecation";
case blink::mojom::ConsoleMessageSource::kWorker:
return "worker";
case blink::mojom::ConsoleMessageSource::kViolation:
return "violation";
case blink::mojom::ConsoleMessageSource::kIntervention:
return "intervention";
case blink::mojom::ConsoleMessageSource::kRecommendation:
return "recommendation";
default:
return "other";
}
}
v8::Local<v8::Value> ServiceWorkerRunningInfoToDict(

View File

@@ -342,7 +342,7 @@ Session::Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context)
// Observe DownloadManager to get download notifications.
browser_context->GetDownloadManager()->AddObserver(this);
new SessionPreferences(browser_context);
SessionPreferences::CreateForBrowserContext(browser_context);
protocol_.Reset(isolate, Protocol::Create(isolate, browser_context).ToV8());

View File

@@ -9,6 +9,7 @@
#include "shell/browser/api/electron_api_system_preferences.h"
#include "base/containers/fixed_flat_map.h"
#include "base/win/core_winrt_util.h"
#include "base/win/windows_types.h"
#include "base/win/wrapped_window_proc.h"
@@ -97,73 +98,45 @@ std::string SystemPreferences::GetAccentColor() {
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
const std::string& color) {
int id;
if (color == "3d-dark-shadow") {
id = COLOR_3DDKSHADOW;
} else if (color == "3d-face") {
id = COLOR_3DFACE;
} else if (color == "3d-highlight") {
id = COLOR_3DHIGHLIGHT;
} else if (color == "3d-light") {
id = COLOR_3DLIGHT;
} else if (color == "3d-shadow") {
id = COLOR_3DSHADOW;
} else if (color == "active-border") {
id = COLOR_ACTIVEBORDER;
} else if (color == "active-caption") {
id = COLOR_ACTIVECAPTION;
} else if (color == "active-caption-gradient") {
id = COLOR_GRADIENTACTIVECAPTION;
} else if (color == "app-workspace") {
id = COLOR_APPWORKSPACE;
} else if (color == "button-text") {
id = COLOR_BTNTEXT;
} else if (color == "caption-text") {
id = COLOR_CAPTIONTEXT;
} else if (color == "desktop") {
id = COLOR_DESKTOP;
} else if (color == "disabled-text") {
id = COLOR_GRAYTEXT;
} else if (color == "highlight") {
id = COLOR_HIGHLIGHT;
} else if (color == "highlight-text") {
id = COLOR_HIGHLIGHTTEXT;
} else if (color == "hotlight") {
id = COLOR_HOTLIGHT;
} else if (color == "inactive-border") {
id = COLOR_INACTIVEBORDER;
} else if (color == "inactive-caption") {
id = COLOR_INACTIVECAPTION;
} else if (color == "inactive-caption-gradient") {
id = COLOR_GRADIENTINACTIVECAPTION;
} else if (color == "inactive-caption-text") {
id = COLOR_INACTIVECAPTIONTEXT;
} else if (color == "info-background") {
id = COLOR_INFOBK;
} else if (color == "info-text") {
id = COLOR_INFOTEXT;
} else if (color == "menu") {
id = COLOR_MENU;
} else if (color == "menu-highlight") {
id = COLOR_MENUHILIGHT;
} else if (color == "menubar") {
id = COLOR_MENUBAR;
} else if (color == "menu-text") {
id = COLOR_MENUTEXT;
} else if (color == "scrollbar") {
id = COLOR_SCROLLBAR;
} else if (color == "window") {
id = COLOR_WINDOW;
} else if (color == "window-frame") {
id = COLOR_WINDOWFRAME;
} else if (color == "window-text") {
id = COLOR_WINDOWTEXT;
} else {
thrower.ThrowError("Unknown color: " + color);
return "";
}
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, int>({
{"3d-dark-shadow", COLOR_3DDKSHADOW},
{"3d-face", COLOR_3DFACE},
{"3d-highlight", COLOR_3DHIGHLIGHT},
{"3d-light", COLOR_3DLIGHT},
{"3d-shadow", COLOR_3DSHADOW},
{"active-border", COLOR_ACTIVEBORDER},
{"active-caption", COLOR_ACTIVECAPTION},
{"active-caption-gradient", COLOR_GRADIENTACTIVECAPTION},
{"app-workspace", COLOR_APPWORKSPACE},
{"button-text", COLOR_BTNTEXT},
{"caption-text", COLOR_CAPTIONTEXT},
{"desktop", COLOR_DESKTOP},
{"disabled-text", COLOR_GRAYTEXT},
{"highlight", COLOR_HIGHLIGHT},
{"highlight-text", COLOR_HIGHLIGHTTEXT},
{"hotlight", COLOR_HOTLIGHT},
{"inactive-border", COLOR_INACTIVEBORDER},
{"inactive-caption", COLOR_INACTIVECAPTION},
{"inactive-caption-gradient", COLOR_GRADIENTINACTIVECAPTION},
{"inactive-caption-text", COLOR_INACTIVECAPTIONTEXT},
{"info-background", COLOR_INFOBK},
{"info-text", COLOR_INFOTEXT},
{"menu", COLOR_MENU},
{"menu-highlight", COLOR_MENUHILIGHT},
{"menu-text", COLOR_MENUTEXT},
{"menubar", COLOR_MENUBAR},
{"scrollbar", COLOR_SCROLLBAR},
{"window", COLOR_WINDOW},
{"window-frame", COLOR_WINDOWFRAME},
{"window-text", COLOR_WINDOWTEXT},
});
return ToRGBHex(color_utils::GetSysSkColor(id));
if (const auto* iter = Lookup.find(color); iter != Lookup.end())
return ToRGBHex(color_utils::GetSysSkColor(iter->second));
thrower.ThrowError("Unknown color: " + color);
return "";
}
std::string SystemPreferences::GetMediaAccessStatus(

View File

@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
#include "base/containers/fixed_flat_map.h"
#include "base/no_destructor.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
@@ -412,62 +413,46 @@ gin::Handle<SimpleURLLoaderWrapper> SimpleURLLoaderWrapper::Create(
request->trusted_params->has_user_activation = has_user_activation;
}
std::string mode;
if (opts.Get("mode", &mode) && !mode.empty()) {
if (mode == "navigate") {
request->mode = network::mojom::RequestMode::kNavigate;
} else if (mode == "cors") {
request->mode = network::mojom::RequestMode::kCors;
} else if (mode == "no-cors") {
request->mode = network::mojom::RequestMode::kNoCors;
} else if (mode == "same-origin") {
request->mode = network::mojom::RequestMode::kSameOrigin;
}
if (std::string mode; opts.Get("mode", &mode)) {
using Val = network::mojom::RequestMode;
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, Val>({
{"cors", Val::kCors},
{"navigate", Val::kNavigate},
{"no-cors", Val::kNoCors},
{"same-origin", Val::kSameOrigin},
});
if (auto* iter = Lookup.find(mode); iter != Lookup.end())
request->mode = iter->second;
}
std::string destination;
if (opts.Get("destination", &destination) && !destination.empty()) {
if (destination == "empty") {
request->destination = network::mojom::RequestDestination::kEmpty;
} else if (destination == "audio") {
request->destination = network::mojom::RequestDestination::kAudio;
} else if (destination == "audioworklet") {
request->destination = network::mojom::RequestDestination::kAudioWorklet;
} else if (destination == "document") {
request->destination = network::mojom::RequestDestination::kDocument;
} else if (destination == "embed") {
request->destination = network::mojom::RequestDestination::kEmbed;
} else if (destination == "font") {
request->destination = network::mojom::RequestDestination::kFont;
} else if (destination == "frame") {
request->destination = network::mojom::RequestDestination::kFrame;
} else if (destination == "iframe") {
request->destination = network::mojom::RequestDestination::kIframe;
} else if (destination == "image") {
request->destination = network::mojom::RequestDestination::kImage;
} else if (destination == "manifest") {
request->destination = network::mojom::RequestDestination::kManifest;
} else if (destination == "object") {
request->destination = network::mojom::RequestDestination::kObject;
} else if (destination == "paintworklet") {
request->destination = network::mojom::RequestDestination::kPaintWorklet;
} else if (destination == "report") {
request->destination = network::mojom::RequestDestination::kReport;
} else if (destination == "script") {
request->destination = network::mojom::RequestDestination::kScript;
} else if (destination == "serviceworker") {
request->destination = network::mojom::RequestDestination::kServiceWorker;
} else if (destination == "style") {
request->destination = network::mojom::RequestDestination::kStyle;
} else if (destination == "track") {
request->destination = network::mojom::RequestDestination::kTrack;
} else if (destination == "video") {
request->destination = network::mojom::RequestDestination::kVideo;
} else if (destination == "worker") {
request->destination = network::mojom::RequestDestination::kWorker;
} else if (destination == "xslt") {
request->destination = network::mojom::RequestDestination::kXslt;
}
if (std::string destination; opts.Get("destination", &destination)) {
using Val = network::mojom::RequestDestination;
static constexpr auto Lookup =
base::MakeFixedFlatMap<base::StringPiece, Val>({
{"audio", Val::kAudio},
{"audioworklet", Val::kAudioWorklet},
{"document", Val::kDocument},
{"embed", Val::kEmbed},
{"empty", Val::kEmpty},
{"font", Val::kFont},
{"frame", Val::kFrame},
{"iframe", Val::kIframe},
{"image", Val::kImage},
{"manifest", Val::kManifest},
{"object", Val::kObject},
{"paintworklet", Val::kPaintWorklet},
{"report", Val::kReport},
{"script", Val::kScript},
{"serviceworker", Val::kServiceWorker},
{"style", Val::kStyle},
{"track", Val::kTrack},
{"video", Val::kVideo},
{"worker", Val::kWorker},
{"xslt", Val::kXslt},
});
if (auto* iter = Lookup.find(destination); iter != Lookup.end())
request->destination = iter->second;
}
bool credentials_specified =

View File

@@ -12,6 +12,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/containers/id_map.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
@@ -379,8 +380,9 @@ namespace electron::api {
namespace {
std::string CursorTypeToString(const ui::Cursor& cursor) {
switch (cursor.type()) {
constexpr base::StringPiece CursorTypeToString(
ui::mojom::CursorType cursor_type) {
switch (cursor_type) {
case ui::mojom::CursorType::kPointer:
return "pointer";
case ui::mojom::CursorType::kCross:
@@ -728,8 +730,8 @@ std::map<std::string, std::string> GetAddedFileSystemPaths(
bool IsDevToolsFileSystemAdded(content::WebContents* web_contents,
const std::string& file_system_path) {
auto file_system_paths = GetAddedFileSystemPaths(web_contents);
return file_system_paths.find(file_system_path) != file_system_paths.end();
return base::Contains(GetAddedFileSystemPaths(web_contents),
file_system_path);
}
void SetBackgroundColor(content::RenderWidgetHostView* rwhv, SkColor color) {
@@ -767,12 +769,7 @@ WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
type_(Type::kRemote),
id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -805,12 +802,7 @@ WebContents::WebContents(v8::Isolate* isolate,
Type type)
: content::WebContentsObserver(web_contents.get()),
type_(type),
id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -826,12 +818,7 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate,
const gin_helper::Dictionary& options)
: id_(GetAllWebContents().Add(this)),
devtools_file_system_indexer_(
base::MakeRefCounted<DevToolsFileSystemIndexer>()),
exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
file_task_runner_(
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
: id_(GetAllWebContents().Add(this))
#if BUILDFLAG(ENABLE_PRINTING)
,
print_task_runner_(CreatePrinterHandlerTaskRunner())
@@ -1393,7 +1380,7 @@ bool WebContents::PlatformHandleKeyboardEvent(
content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (exclusive_access_manager_->HandleUserKeyEvent(event))
if (exclusive_access_manager_.HandleUserKeyEvent(event))
return content::KeyboardEventProcessingResult::HANDLED;
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
@@ -1481,7 +1468,7 @@ void WebContents::OnEnterFullscreenModeForTab(
owner_window()->set_fullscreen_transition_type(
NativeWindow::FullScreenTransitionType::HTML);
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
exclusive_access_manager_.fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
SetHtmlApiFullscreen(true);
@@ -1499,7 +1486,7 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
// This needs to be called before we exit fullscreen on the native window,
// or the controller will incorrectly think we weren't fullscreen and bail.
exclusive_access_manager_->fullscreen_controller()->ExitFullscreenModeForTab(
exclusive_access_manager_.fullscreen_controller()->ExitFullscreenModeForTab(
source);
SetHtmlApiFullscreen(false);
@@ -1558,7 +1545,7 @@ void WebContents::RequestExclusivePointerAccess(
bool last_unlocked_by_target,
bool allowed) {
if (allowed) {
exclusive_access_manager_->mouse_lock_controller()->RequestToLockMouse(
exclusive_access_manager_.mouse_lock_controller()->RequestToLockMouse(
web_contents, user_gesture, last_unlocked_by_target);
} else {
web_contents->GotResponseToLockMouseRequest(
@@ -1578,18 +1565,18 @@ void WebContents::RequestToLockMouse(content::WebContents* web_contents,
}
void WebContents::LostMouseLock() {
exclusive_access_manager_->mouse_lock_controller()->LostMouseLock();
exclusive_access_manager_.mouse_lock_controller()->LostMouseLock();
}
void WebContents::RequestKeyboardLock(content::WebContents* web_contents,
bool esc_key_locked) {
exclusive_access_manager_->keyboard_lock_controller()->RequestKeyboardLock(
exclusive_access_manager_.keyboard_lock_controller()->RequestKeyboardLock(
web_contents, esc_key_locked);
}
void WebContents::CancelKeyboardLockRequest(
content::WebContents* web_contents) {
exclusive_access_manager_->keyboard_lock_controller()
exclusive_access_manager_.keyboard_lock_controller()
->CancelKeyboardLockRequest(web_contents);
}
@@ -3361,14 +3348,14 @@ bool WebContents::IsBeingCaptured() {
void WebContents::OnCursorChanged(const ui::Cursor& cursor) {
if (cursor.type() == ui::mojom::CursorType::kCustom) {
Emit("cursor-changed", CursorTypeToString(cursor),
Emit("cursor-changed", CursorTypeToString(cursor.type()),
gfx::Image::CreateFrom1xBitmap(cursor.custom_bitmap()),
cursor.image_scale_factor(),
gfx::Size(cursor.custom_bitmap().width(),
cursor.custom_bitmap().height()),
cursor.custom_hotspot());
} else {
Emit("cursor-changed", CursorTypeToString(cursor));
Emit("cursor-changed", CursorTypeToString(cursor.type()));
}
}

View File

@@ -14,9 +14,11 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" // nogncheck
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "content/common/frame.mojom.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/keyboard_event_processing_result.h"
@@ -75,8 +77,6 @@ namespace gin {
class Arguments;
}
class ExclusiveAccessManager;
class SkRegion;
namespace electron {
@@ -790,9 +790,10 @@ class WebContents : public ExclusiveAccessContext,
// Whether window is fullscreened by window api.
bool native_fullscreen_ = false;
scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_;
const scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_ =
base::MakeRefCounted<DevToolsFileSystemIndexer>();
std::unique_ptr<ExclusiveAccessManager> exclusive_access_manager_;
ExclusiveAccessManager exclusive_access_manager_{this};
std::unique_ptr<DevToolsEyeDropper> eye_dropper_;
@@ -814,10 +815,11 @@ class WebContents : public ExclusiveAccessContext,
DevToolsIndexingJobsMap;
DevToolsIndexingJobsMap devtools_indexing_jobs_;
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
const scoped_refptr<base::SequencedTaskRunner> file_task_runner_ =
base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
#if BUILDFLAG(ENABLE_PRINTING)
scoped_refptr<base::TaskRunner> print_task_runner_;
const scoped_refptr<base::TaskRunner> print_task_runner_;
#endif
// Stores the frame thats currently in fullscreen, nullptr if there is none.

View File

@@ -8,6 +8,7 @@
#include <string>
#include <utility>
#include "base/containers/contains.h"
#include "base/stl_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/values.h"
@@ -294,7 +295,7 @@ bool WebRequest::RequestFilter::MatchesURL(const GURL& url) const {
bool WebRequest::RequestFilter::MatchesType(
extensions::WebRequestResourceType type) const {
return types_.empty() || types_.find(type) != types_.end();
return types_.empty() || base::Contains(types_, type);
}
bool WebRequest::RequestFilter::MatchesRequest(

View File

@@ -8,6 +8,7 @@
#include <unordered_set>
#include <utility>
#include "base/containers/contains.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "gin/arguments.h"
@@ -221,7 +222,7 @@ std::vector<blink::MessagePortChannel> MessagePort::DisentanglePorts(
// or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
for (unsigned i = 0; i < ports.size(); ++i) {
auto* port = ports[i].get();
if (!port || port->IsNeutered() || visited.find(port) != visited.end()) {
if (!port || port->IsNeutered() || base::Contains(visited, port)) {
std::string type;
if (!port)
type = "null";

View File

@@ -149,8 +149,7 @@ void HidChooserController::OnDeviceAdded(
void HidChooserController::OnDeviceRemoved(
const device::mojom::HidDeviceInfo& device) {
auto id = PhysicalDeviceIdFromDeviceInfo(device);
auto items_it = std::find(items_.begin(), items_.end(), id);
if (items_it == items_.end())
if (!base::Contains(items_, id))
return;
api::Session* session = GetSession();
if (session) {

View File

@@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
@@ -725,9 +726,7 @@ int NativeWindow::NonClientHitTest(const gfx::Point& point) {
void NativeWindow::AddDraggableRegionProvider(
DraggableRegionProvider* provider) {
if (std::find(draggable_region_providers_.begin(),
draggable_region_providers_.end(),
provider) == draggable_region_providers_.end()) {
if (!base::Contains(draggable_region_providers_, provider)) {
draggable_region_providers_.push_back(provider);
}
}

View File

@@ -157,6 +157,7 @@ class NativeWindowMac : public NativeWindow,
bool IsActive() const override;
// Remove the specified child window without closing it.
void RemoveChildWindow(NativeWindow* child) override;
void RemoveChildFromParentWindow(NativeWindow* child);
// Attach child windows, if the window is visible.
void AttachChildren() override;
// Detach window from parent without destroying it.

View File

@@ -389,6 +389,9 @@ void NativeWindowMac::Close() {
return;
}
// Ensure we're detached from the parent window before closing.
RemoveChildFromParentWindow(this);
// If a sheet is attached to the window when we call
// [window_ performClose:nil], the window won't close properly
// even after the user has ended the sheet.
@@ -406,6 +409,8 @@ void NativeWindowMac::Close() {
}
void NativeWindowMac::CloseImmediately() {
RemoveChildFromParentWindow(this);
// Retain the child window before closing it. If the last reference to the
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
// See e.g. http://crbug.com/616701.
@@ -599,6 +604,11 @@ void NativeWindowMac::RemoveChildWindow(NativeWindow* child) {
[window_ removeChildWindow:child->GetNativeWindow().GetNativeNSWindow()];
}
void NativeWindowMac::RemoveChildFromParentWindow(NativeWindow* child) {
if (parent())
parent()->RemoveChildWindow(child);
}
void NativeWindowMac::AttachChildren() {
for (auto* child : child_windows_) {
auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow();
@@ -1779,27 +1789,27 @@ void NativeWindowMac::InternalSetWindowButtonVisibility(bool visible) {
[[window_ standardWindowButton:NSWindowZoomButton] setHidden:!visible];
}
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
void NativeWindowMac::InternalSetParentWindow(NativeWindow* new_parent,
bool attach) {
if (is_modal())
return;
NativeWindow::SetParentWindow(parent);
// Do not remove/add if we are already properly attached.
if (attach && parent &&
[window_ parentWindow] == parent->GetNativeWindow().GetNativeNSWindow())
if (attach && new_parent &&
[window_ parentWindow] ==
new_parent->GetNativeWindow().GetNativeNSWindow())
return;
// Remove current parent window.
if ([window_ parentWindow])
parent->RemoveChildWindow(this);
RemoveChildFromParentWindow(this);
// Set new parent window.
if (parent && attach) {
parent->add_child_window(this);
parent->AttachChildren();
if (new_parent && attach) {
new_parent->add_child_window(this);
new_parent->AttachChildren();
}
NativeWindow::SetParentWindow(new_parent);
}
void NativeWindowMac::SetForwardMouseMessages(bool forward) {

View File

@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/cxx17_backports.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -730,10 +731,14 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
gfx::Rect());
// Auto-hide menubar when in fullscreen.
if (fullscreen)
if (fullscreen) {
menu_bar_visible_before_fullscreen_ = IsMenuBarVisible();
SetMenuBarVisibility(false);
else
SetMenuBarVisibility(!IsMenuBarAutoHide());
} else {
SetMenuBarVisibility(!IsMenuBarAutoHide() &&
menu_bar_visible_before_fullscreen_);
menu_bar_visible_before_fullscreen_ = false;
}
#endif
}
@@ -1435,8 +1440,7 @@ bool NativeWindowViews::IsVisibleOnAllWorkspaces() {
std::vector<x11::Atom> wm_states;
GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
x11::GetAtom("_NET_WM_STATE"), &wm_states);
return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
wm_states.end();
return base::Contains(wm_states, sticky_atom);
}
#endif
return false;

View File

@@ -320,6 +320,9 @@ class NativeWindowViews : public NativeWindow,
// Handles unhandled keyboard messages coming back from the renderer process.
views::UnhandledKeyboardEventHandler keyboard_event_handler_;
// Whether the menubar is visible before the window enters fullscreen
bool menu_bar_visible_before_fullscreen_ = false;
// Whether the window should be enabled based on user calls to SetEnabled()
bool is_enabled_ = true;
// How many modal children this window has;

View File

@@ -726,10 +726,8 @@ void OffScreenRenderWidgetHostView::CompositeFrame(
}
}
paint_callback_running_ = true;
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
frame);
paint_callback_running_ = false;
ReleaseResize();
}

View File

@@ -18,7 +18,6 @@
#include "base/process/kill.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/browser/renderer_host/delegated_frame_host.h" // nogncheck
@@ -258,9 +257,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
int frame_rate_ = 0;
int frame_rate_threshold_us_ = 0;
base::Time last_time_ = base::Time::Now();
gfx::Vector2dF last_scroll_offset_;
gfx::Size size_;
bool painting_;
@@ -271,8 +267,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
bool hold_resize_ = false;
bool pending_resize_ = false;
bool paint_callback_running_ = false;
viz::LocalSurfaceId delegated_frame_host_surface_id_;
viz::ParentLocalSurfaceIdAllocator delegated_frame_host_allocator_;

View File

@@ -6,6 +6,7 @@
#include <utility>
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "build/build_config.h"
#include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
@@ -100,8 +101,7 @@ void PrintViewManagerElectron::GetDefaultPrintSettings(
void PrintViewManagerElectron::ScriptedPrint(
printing::mojom::ScriptedPrintParamsPtr params,
ScriptedPrintCallback callback) {
auto entry = std::find(pdf_jobs_.begin(), pdf_jobs_.end(), params->cookie);
if (entry == pdf_jobs_.end()) {
if (!base::Contains(pdf_jobs_, params->cookie)) {
PrintViewManagerBase::ScriptedPrint(std::move(params), std::move(callback));
return;
}
@@ -151,8 +151,7 @@ void PrintViewManagerElectron::CheckForCancel(int32_t preview_ui_id,
void PrintViewManagerElectron::DidGetPrintedPagesCount(int32_t cookie,
uint32_t number_pages) {
auto entry = std::find(pdf_jobs_.begin(), pdf_jobs_.end(), cookie);
if (entry == pdf_jobs_.end()) {
if (!base::Contains(pdf_jobs_, cookie)) {
PrintViewManagerBase::DidGetPrintedPagesCount(cookie, number_pages);
}
}

View File

@@ -13,10 +13,15 @@ namespace electron {
// static
int SessionPreferences::kLocatorKey = 0;
SessionPreferences::SessionPreferences(content::BrowserContext* context) {
context->SetUserData(&kLocatorKey, base::WrapUnique(this));
// static
void SessionPreferences::CreateForBrowserContext(
content::BrowserContext* context) {
DCHECK(context);
context->SetUserData(&kLocatorKey,
base::WrapUnique(new SessionPreferences{}));
}
SessionPreferences::SessionPreferences() = default;
SessionPreferences::~SessionPreferences() = default;
// static

View File

@@ -23,7 +23,8 @@ class SessionPreferences : public base::SupportsUserData::Data {
static std::vector<base::FilePath> GetValidPreloads(
content::BrowserContext* context);
explicit SessionPreferences(content::BrowserContext* context);
static void CreateForBrowserContext(content::BrowserContext* context);
~SessionPreferences() override;
void set_preloads(const std::vector<base::FilePath>& preloads) {
@@ -32,6 +33,8 @@ class SessionPreferences : public base::SupportsUserData::Data {
const std::vector<base::FilePath>& preloads() const { return preloads_; }
private:
SessionPreferences();
// The user data key.
static int kLocatorKey;

View File

@@ -44,10 +44,6 @@ class InspectableWebContentsView {
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
// Returns the container control, which has devtools view attached.
virtual views::View* GetView() = 0;
// Returns the web view control, which can be used by the
// GetInitiallyFocusedView() to set initial focus to web view.
virtual views::View* GetWebView() = 0;
#else
virtual gfx::NativeView GetNativeView() const = 0;
#endif

View File

@@ -242,7 +242,7 @@ DialogResult ShowTaskDialogWstr(gfx::AcceleratedWidget parent,
TaskDialogIndirect(&config, &id, nullptr, &verification_flag_checked);
int button_id;
if (id_map.find(id) != id_map.end()) // common button.
if (base::Contains(id_map, id)) // common button.
button_id = id_map[id];
else if (id >= kIDStart) // custom button.
button_id = id - kIDStart;

View File

@@ -109,10 +109,6 @@ views::View* InspectableWebContentsViewViews::GetView() {
return this;
}
views::View* InspectableWebContentsViewViews::GetWebView() {
return contents_web_view_;
}
void InspectableWebContentsViewViews::ShowDevTools(bool activate) {
if (devtools_visible_)
return;

View File

@@ -31,7 +31,6 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView,
// InspectableWebContentsView:
views::View* GetView() override;
views::View* GetWebView() override;
void ShowDevTools(bool activate) override;
void CloseDevTools() override;
bool IsDevToolsViewShowing() override;

View File

@@ -153,6 +153,7 @@ void WinCaptionButtonContainer::UpdateButtons() {
const bool minimizable = frame_view_->window()->IsMinimizable();
minimize_button_->SetEnabled(minimizable);
minimize_button_->SetVisible(minimizable);
// In touch mode, windows cannot be taken out of fullscreen or tiled mode, so
// the maximize/restore button should be disabled.

View File

@@ -19,7 +19,8 @@
namespace {
std::string MediaStreamTypeToString(blink::mojom::MediaStreamType type) {
constexpr base::StringPiece MediaStreamTypeToString(
blink::mojom::MediaStreamType type) {
switch (type) {
case blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE:
return "audio";

View File

@@ -6,6 +6,7 @@
#include <map>
#include "base/containers/contains.h"
#include "base/strings/utf_string_conversions.h"
#include "shell/common/gin_converters/image_converter.h"
#include "shell/common/gin_helper/dictionary.h"
@@ -71,7 +72,7 @@ std::string Clipboard::Read(const std::string& format_string) {
clipboard->ExtractCustomPlatformNames(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr);
#if BUILDFLAG(IS_LINUX)
if (custom_format_names.find(format_string) == custom_format_names.end()) {
if (!base::Contains(custom_format_names, format_string)) {
custom_format_names =
clipboard->ExtractCustomPlatformNames(ui::ClipboardBuffer::kSelection,
/* data_dst = */ nullptr);
@@ -79,7 +80,7 @@ std::string Clipboard::Read(const std::string& format_string) {
#endif
ui::ClipboardFormatType format;
if (custom_format_names.find(format_string) != custom_format_names.end()) {
if (base::Contains(custom_format_names, format_string)) {
format =
ui::ClipboardFormatType(ui::ClipboardFormatType::CustomPlatformType(
custom_format_names[format_string]));

View File

@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
@@ -100,8 +101,7 @@ void ElectronBindings::EnvironmentDestroyed(node::Environment* env) {
void ElectronBindings::ActivateUVLoop(v8::Isolate* isolate) {
node::Environment* env = node::Environment::GetCurrent(isolate);
if (std::find(pending_next_ticks_.begin(), pending_next_ticks_.end(), env) !=
pending_next_ticks_.end())
if (base::Contains(pending_next_ticks_, env))
return;
pending_next_ticks_.push_back(env);

View File

@@ -180,9 +180,9 @@ struct Converter<blink::WebInputEvent::Modifiers> {
}
};
std::vector<std::string> ModifiersToArray(int modifiers) {
std::vector<base::StringPiece> ModifiersToArray(int modifiers) {
using Modifiers = blink::WebInputEvent::Modifiers;
std::vector<std::string> modifier_strings;
std::vector<base::StringPiece> modifier_strings;
if (modifiers & Modifiers::kShiftKey)
modifier_strings.push_back("shift");
if (modifiers & Modifiers::kControlKey)

View File

@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "v8/include/v8.h"
namespace electron {
@@ -51,7 +52,7 @@ class KeyWeakMap {
}
// Whether there is an object with |key| in this WeakMap.
bool Has(const K& key) const { return map_.find(key) != map_.end(); }
constexpr bool Has(const K& key) const { return base::Contains(map_, key); }
// Returns all objects.
std::vector<v8::Local<v8::Object>> Values(v8::Isolate* isolate) const {

View File

@@ -6,14 +6,13 @@
#include <algorithm>
#include <memory>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/containers/fixed_flat_set.h"
#include "base/environment.h"
#include "base/path_service.h"
#include "base/run_loop.h"
@@ -236,32 +235,39 @@ void ErrorMessageListener(v8::Local<v8::Message> message,
}
}
const std::unordered_set<base::StringPiece, base::StringPieceHash>
GetAllowedDebugOptions() {
if (electron::fuses::IsNodeCliInspectEnabled()) {
// Only allow DebugOptions in non-ELECTRON_RUN_AS_NODE mode
return {
"--inspect", "--inspect-brk",
"--inspect-port", "--debug",
"--debug-brk", "--debug-port",
"--inspect-brk-node", "--inspect-publish-uid",
};
}
// If node CLI inspect support is disabled, allow no debug options.
return {};
// Only allow DebugOptions in non-ELECTRON_RUN_AS_NODE mode.
// If node CLI inspect support is disabled, allow no debug options.
bool IsAllowedDebugOption(base::StringPiece option) {
static constexpr auto options = base::MakeFixedFlatSet<base::StringPiece>({
"--debug",
"--debug-brk",
"--debug-port",
"--inspect",
"--inspect-brk",
"--inspect-brk-node",
"--inspect-port",
"--inspect-publish-uid",
});
return electron::fuses::IsNodeCliInspectEnabled() && options.contains(option);
}
// Initialize NODE_OPTIONS to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_node_options_options
void SetNodeOptions(base::Environment* env) {
// Options that are unilaterally disallowed
const std::set<std::string> disallowed = {
"--openssl-config", "--use-bundled-ca", "--use-openssl-ca",
"--force-fips", "--enable-fips"};
static constexpr auto disallowed = base::MakeFixedFlatSet<base::StringPiece>({
"--enable-fips",
"--force-fips",
"--openssl-config",
"--use-bundled-ca",
"--use-openssl-ca",
});
// Subset of options allowed in packaged apps
const std::set<std::string> allowed_in_packaged = {"--max-http-header-size",
"--http-parser"};
static constexpr auto pkg_opts = base::MakeFixedFlatSet<base::StringPiece>({
"--http-parser",
"--max-http-header-size",
});
if (env->HasVar("NODE_OPTIONS")) {
if (electron::fuses::IsNodeOptionsEnabled()) {
@@ -276,13 +282,12 @@ void SetNodeOptions(base::Environment* env) {
// Strip off values passed to individual NODE_OPTIONs
std::string option = part.substr(0, part.find('='));
if (is_packaged_app &&
allowed_in_packaged.find(option) == allowed_in_packaged.end()) {
if (is_packaged_app && !pkg_opts.contains(option)) {
// Explicitly disallow majority of NODE_OPTIONS in packaged apps
LOG(ERROR) << "Most NODE_OPTIONs are not supported in packaged apps."
<< " See documentation for more details.";
options.erase(options.find(option), part.length());
} else if (disallowed.find(option) != disallowed.end()) {
} else if (disallowed.contains(option)) {
// Remove NODE_OPTIONS specifically disallowed for use in Node.js
// through Electron owing to constraints like BoringSSL.
LOG(ERROR) << "The NODE_OPTION " << option
@@ -383,9 +388,6 @@ bool NodeBindings::IsInitialized() {
// Initialize Node.js cli options to pass to Node.js
// See https://nodejs.org/api/cli.html#cli_options
void NodeBindings::SetNodeCliFlags() {
const std::unordered_set<base::StringPiece, base::StringPieceHash> allowed =
GetAllowedDebugOptions();
const auto argv = base::CommandLine::ForCurrentProcess()->argv();
std::vector<std::string> args;
@@ -404,7 +406,7 @@ void NodeBindings::SetNodeCliFlags() {
const auto stripped = base::StringPiece(option).substr(0, option.find('='));
// Only allow in no-op (--) option or DebugOptions
if (allowed.count(stripped) != 0 || stripped == "--")
if (IsAllowedDebugOption(stripped) || stripped == "--")
args.push_back(option);
}

View File

@@ -10,6 +10,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
@@ -63,7 +64,7 @@ bool DeepFreeze(const v8::Local<v8::Object>& object,
const v8::Local<v8::Context>& context,
std::set<int> frozen = std::set<int>()) {
int hash = object->GetIdentityHash();
if (frozen.find(hash) != frozen.end())
if (base::Contains(frozen, hash))
return true;
frozen.insert(hash);

View File

@@ -11,6 +11,7 @@
#include <utility>
#include <vector>
#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/single_thread_task_runner.h"
@@ -192,13 +193,13 @@ void SpellCheckClient::OnSpellCheckDone(
auto& word_list = pending_request_param_->wordlist();
for (const auto& word : word_list) {
if (misspelled.find(word.text) != misspelled.end()) {
if (base::Contains(misspelled, word.text)) {
// If this is a contraction, iterate through parts and accept the word
// if none of them are misspelled
if (!word.contraction_words.empty()) {
auto all_correct = true;
for (const auto& contraction_word : word.contraction_words) {
if (misspelled.find(contraction_word) != misspelled.end()) {
if (base::Contains(misspelled, contraction_word)) {
all_correct = false;
break;
}

View File

@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/spellcheck/renderer/spellcheck.h"
#include "content/public/renderer/render_frame.h"
@@ -383,7 +384,7 @@ class WebFrameRenderer : public gin::Wrappable<WebFrameRenderer>,
private:
bool MaybeGetRenderFrame(v8::Isolate* isolate,
const std::string& method_name,
const base::StringPiece method_name,
content::RenderFrame** render_frame_ptr) {
std::string error_msg;
if (!MaybeGetRenderFrame(&error_msg, method_name, render_frame_ptr)) {
@@ -394,13 +395,13 @@ class WebFrameRenderer : public gin::Wrappable<WebFrameRenderer>,
}
bool MaybeGetRenderFrame(std::string* error_msg,
const std::string& method_name,
const base::StringPiece method_name,
content::RenderFrame** render_frame_ptr) {
auto* frame = render_frame();
if (!frame) {
*error_msg = "Render frame was torn down before webFrame." + method_name +
" could be "
"executed";
*error_msg = base::StreamableToString(
"Render frame was torn down before webFrame.", method_name,
" could be executed");
return false;
}
*render_frame_ptr = frame;

View File

@@ -63,7 +63,7 @@ void ElectronRenderFrameObserver::DidClearWindowObject() {
// Check DidInstallConditionalFeatures below for the background.
auto* web_frame =
static_cast<blink::WebLocalFrameImpl*>(render_frame_->GetWebFrame());
if (has_delayed_node_initialization_ && web_frame->Opener() &&
if (has_delayed_node_initialization_ &&
!web_frame->IsOnInitialEmptyDocument()) {
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);

View File

@@ -7,6 +7,7 @@
#include <string>
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "content/public/renderer/render_frame.h"
#include "electron/buildflags/buildflags.h"
#include "net/http/http_request_headers.h"
@@ -195,15 +196,13 @@ void ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread(
node::Environment* ElectronRendererClient::GetEnvironment(
content::RenderFrame* render_frame) const {
if (injected_frames_.find(render_frame) == injected_frames_.end())
if (!base::Contains(injected_frames_, render_frame))
return nullptr;
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
auto context =
GetContext(render_frame->GetWebFrame(), v8::Isolate::GetCurrent());
node::Environment* env = node::Environment::GetCurrent(context);
if (environments_.find(env) == environments_.end())
return nullptr;
return env;
return base::Contains(environments_, env) ? env : nullptr;
}
} // namespace electron

View File

@@ -217,7 +217,7 @@ void ElectronSandboxedRendererClient::WillReleaseScriptContext(
void ElectronSandboxedRendererClient::EmitProcessEvent(
content::RenderFrame* render_frame,
const char* event_name) {
if (injected_frames_.find(render_frame) == injected_frames_.end())
if (!base::Contains(injected_frames_, render_frame))
return;
auto* isolate = blink::MainThreadIsolate();

View File

@@ -257,6 +257,20 @@ describe('BrowserView module', () => {
w.removeBrowserView(view);
}).to.not.throw();
});
it('can be called on a BrowserView with a destroyed webContents', (done) => {
view = new BrowserView();
w.addBrowserView(view);
view.webContents.on('destroyed', () => {
w.removeBrowserView(view);
done();
});
view.webContents.loadURL('data:text/html,hello there').then(() => {
view.webContents.close();
});
});
});
describe('BrowserWindow.getBrowserViews()', () => {

View File

@@ -3304,6 +3304,9 @@ describe('BrowserWindow module', () => {
expect(test.version).to.equal(process.version);
expect(test.versions).to.deep.equal(process.versions);
expect(test.contextId).to.be.a('string');
expect(test.nodeEvents).to.equal(true);
expect(test.nodeTimers).to.equal(true);
expect(test.nodeUrl).to.equal(true);
if (process.platform === 'linux' && test.osSandbox) {
expect(test.creationTime).to.be.null('creation time');
@@ -4267,6 +4270,21 @@ describe('BrowserWindow module', () => {
expect(w.getChildWindows().length).to.equal(0);
});
it('can handle child window close and reparent multiple times', async () => {
const w = new BrowserWindow({ show: false });
let c: BrowserWindow | null;
for (let i = 0; i < 5; i++) {
c = new BrowserWindow({ show: false, parent: w });
const closed = emittedOnce(c, 'closed');
c.close();
await closed;
}
await delay();
expect(w.getChildWindows().length).to.equal(0);
});
ifit(process.platform === 'darwin')('child window matches visibility when visibility changes', async () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });
@@ -4930,6 +4948,48 @@ describe('BrowserWindow module', () => {
});
});
ifdescribe(process.platform !== 'darwin')('when fullscreen state is changed', () => {
it('correctly remembers state prior to fullscreen change', async () => {
const w = new BrowserWindow({ show: false });
expect(w.isMenuBarVisible()).to.be.true('isMenuBarVisible');
w.setMenuBarVisibility(false);
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
const enterFS = emittedOnce(w, 'enter-full-screen');
w.setFullScreen(true);
await enterFS;
expect(w.fullScreen).to.be.true('not fullscreen');
const exitFS = emittedOnce(w, 'leave-full-screen');
w.setFullScreen(false);
await exitFS;
expect(w.fullScreen).to.be.false('not fullscreen');
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
});
it('correctly remembers state prior to fullscreen change with autoHide', async () => {
const w = new BrowserWindow({ show: false });
expect(w.autoHideMenuBar).to.be.false('autoHideMenuBar');
w.autoHideMenuBar = true;
expect(w.autoHideMenuBar).to.be.true('autoHideMenuBar');
w.setMenuBarVisibility(false);
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
const enterFS = emittedOnce(w, 'enter-full-screen');
w.setFullScreen(true);
await enterFS;
expect(w.fullScreen).to.be.true('not fullscreen');
const exitFS = emittedOnce(w, 'leave-full-screen');
w.setFullScreen(false);
await exitFS;
expect(w.fullScreen).to.be.false('not fullscreen');
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
});
});
ifdescribe(process.platform === 'darwin')('fullscreenable state', () => {
it('with functions', () => {
it('can be set with fullscreenable constructor option', () => {

View File

@@ -8,7 +8,7 @@ import * as path from 'path';
import * as fs from 'fs';
import * as url from 'url';
import * as ChildProcess from 'child_process';
import { EventEmitter } from 'events';
import { EventEmitter, once } from 'events';
import { promisify } from 'util';
import { ifit, ifdescribe, defer, delay, itremote } from './lib/spec-helpers';
import { AddressInfo } from 'net';
@@ -1147,6 +1147,23 @@ describe('chromium features', () => {
expect(eventData).to.equal('size: 350 450');
});
it('loads preload script after setting opener to null', async () => {
const w = new BrowserWindow({ show: false });
w.webContents.setWindowOpenHandler(() => ({
action: 'allow',
overrideBrowserWindowOptions: {
webPreferences: {
preload: path.join(fixturesPath, 'module', 'preload.js')
}
}
}));
w.loadURL('about:blank');
w.webContents.executeJavaScript('window.child = window.open(); child.opener = null');
const [, { webContents }] = await once(app, 'browser-window-created');
const [,, message] = await once(webContents, 'console-message');
expect(message).to.equal('{"require":"function","module":"undefined","process":"object","Buffer":"function"}');
});
it('disables the <webview> tag when it is disabled on the parent window', async () => {
const windowUrl = url.pathToFileURL(path.join(fixturesPath, 'pages', 'window-opener-no-webview-tag.html'));
windowUrl.searchParams.set('p', `${fixturesPath}/pages/window-opener-webview.html`);

View File

@@ -34,6 +34,9 @@
cpuUsage: invoke(() => process.getCPUUsage()),
ioCounters: invoke(() => process.getIOCounters()),
uptime: invoke(() => process.uptime()),
nodeEvents: invoke(() => require('events') === require('node:events')),
nodeTimers: invoke(() => require('timers') === require('node:timers')),
nodeUrl: invoke(() => require('url') === require('node:url')),
env: process.env,
execPath: process.execPath,
pid: process.pid,