Compare commits

...

14 Commits

Author SHA1 Message Date
David Sanders
5b48fa0318 build: use Xcode 13.4.1 (#38825) 2023-06-18 21:43:48 +02:00
Pedro Pontes
be1c22ecab chore: cherry-pick 3 changes from Release-2-M114 (#38788)
* chore: [23-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 16:41:54 -04:00
Keeley Hammond
2c822ce4ac chore: cherry-pick 7 changes from Release-1-M113 (#38331)
* chore: [23-x-y] cherry-pick 8 changes from Release-1-M113

* 91fce3345668 from v8
* 2c8a019f39d2 from v8
* b8020e1973d7 from v8
* d6272b794cbb from chromium
* 48785f698b1c from chromium
* d0ee0197ddff from angle
* 9b6ca211234b from chromium
* 675562695049 from chromium

* chore: clean up patches, delete bad patch

* chore: cherry-pick bb90b9cfcbca from v8

* build: fixup angle patch

* build: fixup v8 patches

* chore: fixup Handle empty ranges in unicode sets patch

* build: drop python2 from CI (#38303)

(cherry picked from commit a22e2a778e)
(cherry picked from commit 9bdd4738ae)

* chore: update patches for 110

* refactor: add WebViewGuestDelegate::GetGuestDelegateWeakPtr()

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

This approach copied from GuestViewBase::GetGuestDelegateWeakPtr() approach in that same commit.

(cherry picked from commit 3f3ab39e3a1077f71aa90319d7a81d53cfb3c55e)

* chore: cherry-pick bae60787d3e9 from dawn

* chore: delete unnecessary patches

* Revert "refactor: add WebViewGuestDelegate::GetGuestDelegateWeakPtr()"

This reverts commit 07a42e351e.

* chore: remove unneeded patch

* chore: update patches

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-12 17:36:35 -04:00
trop[bot]
f4041c10cf fix: menu bar visibility when exiting full screen (#38680)
* fix: menu bar visibility when exiting full screen

Co-authored-by: wgsheng <88312105+wugaosheng123@users.noreply.github.com>

* Update api-browser-window-spec.ts

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: wgsheng <88312105+wugaosheng123@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-12 15:50:20 +02:00
Keeley Hammond
60c84cbd77 chore: cherry-pick 8 changes from Release-0-M114 (#38533)
* chore: [23-x-y] cherry-pick 6 changes from Release-0-M114

* c6ec59dcae7d from angle
* 93c6be3a42e7 from chromium
* e6b75a8b4900 from chromium
* 3b0607d14060 from v8
* 9c6dfc733fce from v8
* ea1cd76358e0 from chromium

* chore: remove 2 invalid patches, fix 2 others

* chore: add missing backports.

* chore: fix backports.

* chore: further fix a backport

* chore: update patches

---------

Co-authored-by: Pedro Pontes <pepontes@microsoft.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-06-09 12:24:25 -07:00
trop[bot]
523fa39765 build: move uploadIndexJson to just before publishRelease (#38700)
* 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:27 -07:00
Pedro Pontes
d368492bfd chore: cherry-pick 2 changes from Release-1-M114 (#38652)
* chore: [23-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:51 -07:00
trop[bot]
3c269d74c9 build: improve error output in release.js (#38661)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-06-07 23:47:58 -07:00
Keeley Hammond
5bbcc22b8d build: uuaw @octokit/request to 6.2.5 (#38645) 2023-06-07 14:26:35 -07:00
trop[bot]
9abb7fb7e3 fix: account for BrowserView bounds in setting autofill popup bounds (#38607)
fix: account for BrowserView bounds in setting autofill popup bounds

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-06 16:00:14 -04:00
trop[bot]
364390e039 chore: make contentTracing.stopRecording() failure clearer (#38518)
chore: make contentTracing.stopRecording() failure clearer

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-05 16:13:15 +09:00
trop[bot]
b59963cf04 fix: DCHECK minimizing parent window with non-modal child (#38507)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-06-02 09:52:46 +02:00
John Kleinschmidt
7a026ed3dc build: drop python2 from CI (#38303) (#38549)
(cherry picked from commit a22e2a778e)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
2023-06-01 15:03:40 -04:00
trop[bot]
75b7a858ac docs: add <webview> new-window event removal to breaking-changes.md (#38526)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <miburda@microsoft.com>
2023-05-31 14:29:26 -04:00
46 changed files with 3274 additions and 83 deletions

View File

@@ -54,7 +54,7 @@ executors:
type: enum
enum: ["macos.x86.medium.gen2", "large"]
macos:
xcode: 13.3.0
xcode: 13.4.1
resource_class: << parameters.size >>
# Electron Runners
@@ -287,7 +287,7 @@ step-gclient-sync: &step-gclient-sync
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
if [ "$IS_RELEASE" != "true" ]; then
# Re-export all the patches to check if there were changes.
python src/electron/script/export_all_patches.py src/electron/patches/config.json
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron
git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then
@@ -341,8 +341,8 @@ step-setup-goma-for-build: &step-setup-goma-for-build
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
export GOMA_FALLBACK_ON_AUTH_FAILURE=true
third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
python3 third_party/goma/goma_ctl.py ensure_start
if [ ! -z "$RAW_GOMA_AUTH" ] && [ "`python3 third_party/goma/goma_auth.py info`" != "Login as Fermi Planck" ]; then
echo "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token."
exit 1
fi
@@ -370,14 +370,14 @@ step-restore-brew-cache: &step-restore-brew-cache
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
keys:
- v6-brew-cache-{{ arch }}
- v7-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Cellar/gnu-tar
- /usr/local/bin/gtar
key: v6-brew-cache-{{ arch }}
key: v7-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
@@ -680,9 +680,9 @@ step-verify-mksnapshot: &step-verify-mksnapshot
if [ "$IS_ASAN" != "1" ]; then
cd src
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
else
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
fi
fi
@@ -692,7 +692,7 @@ step-verify-chromedriver: &step-verify-chromedriver
command: |
if [ "$IS_ASAN" != "1" ]; then
cd src
python electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
python3 electron/script/verify-chromedriver.py --source-root "$PWD" --build-dir out/Default
fi
step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
@@ -818,7 +818,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
elif [ "`uname`" == "Darwin" ]; then
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
fi
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
mkdir cross-arch-snapshots
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
# Clean up so that ninja does not get confused
@@ -975,7 +975,6 @@ step-ts-compile: &step-ts-compile
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- install-python2-mac
- *step-setup-goma-for-build
- checkout-from-cache
- *step-setup-env-for-build
@@ -994,31 +993,6 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
# Command Aliases
commands:
install-python2-mac:
steps:
- restore_cache:
keys:
- v2.7.18-python-cache-{{ arch }}
name: Restore python cache
- run:
name: Install python2 on macos
command: |
if [ "`uname`" == "Darwin" ] && [ "$IS_ELECTRON_RUNNER" != "1" ]; then
if [ ! -f "python-downloads/python-2.7.18-macosx10.9.pkg" ]; then
mkdir python-downloads
echo 'Downloading Python 2.7.18'
curl -O https://dev-cdn.electronjs.org/python/python-2.7.18-macosx10.9.pkg
mv python-2.7.18-macosx10.9.pkg python-downloads
else
echo 'Using Python install from cache'
fi
sudo installer -pkg python-downloads/python-2.7.18-macosx10.9.pkg -target /
fi
- save_cache:
paths:
- python-downloads
key: v2.7.18-python-cache-{{ arch }}
name: Persisting python cache
maybe-restore-portaled-src-cache:
parameters:
halt-if-successful:
@@ -1315,7 +1289,6 @@ commands:
- run: rm -rf src/electron
- *step-restore-brew-cache
- *step-install-gnutar-on-mac
- install-python2-mac
- *step-save-brew-cache
- when:
condition: << parameters.build >>
@@ -1476,7 +1449,6 @@ commands:
- *step-setup-linux-for-headless-testing
- *step-restore-brew-cache
- *step-fix-known-hosts-linux
- install-python2-mac
- *step-install-signing-cert-on-mac
- run:
@@ -1586,7 +1558,6 @@ commands:
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- install-python2-mac
- *step-get-more-space-on-mac
- when:
condition: << parameters.checkout >>

View File

@@ -154,6 +154,39 @@ webContents.setWindowOpenHandler((details) => {
})
```
### Removed: `<webview>` `new-window` event
The `new-window` event of `<webview>` has been removed. There is no direct replacement.
```js
// Removed in Electron 22
webview.addEventListener('new-window', (event) => {})
```
```javascript fiddle='docs/fiddles/ipc/webview-new-window'
// Replace with
// main.js
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
wc.setWindowOpenHandler((details) => {
mainWindow.webContents.send('webview-new-window', wc.id, details)
return { action: 'deny' }
})
})
// preload.js
const { ipcRenderer } = require('electron')
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
console.log('webview-new-window', webContentsId, details)
document.getElementById('webview').dispatchEvent(new Event('new-window'))
})
// renderer.js
document.getElementById('webview').addEventListener('new-window', () => {
console.log('got new-window event')
})
```
### Deprecated: BrowserWindow `scroll-touch-*` events
The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on

View File

@@ -0,0 +1,3 @@
<body>
<a href="child.html" target="_blank">new window</a>
</body>

View File

@@ -0,0 +1,4 @@
<body>
<webview id=webview src="child.html" allowpopups></webview>
<script src="renderer.js"></script>
</body>

View File

@@ -0,0 +1,51 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
webviewTag: true
}
})
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
wc.setWindowOpenHandler((details) => {
mainWindow.webContents.send('webview-new-window', wc.id, details)
return { action: 'deny' }
})
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -0,0 +1,6 @@
const { ipcRenderer } = require('electron')
const webview = document.getElementById('webview')
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
console.log('webview-new-window', webContentsId, details)
webview.dispatchEvent(new Event('new-window'))
})

View File

@@ -0,0 +1,4 @@
const webview = document.getElementById('webview')
webview.addEventListener('new-window', () => {
console.log('got new-window event')
})

View File

@@ -1,3 +1,4 @@
fix_rename_webswapcgllayer_to_webswapcgllayerchromium.patch
cherry-pick-6da1a8953313.patch
cherry-pick-aed05b609629.patch
cherry-pick-d0ee0197ddff.patch

View File

@@ -0,0 +1,214 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Wed, 3 May 2023 13:41:36 -0400
Subject: WebGL: Limit total size of private data
... not just individual arrays.
Bug: chromium:1431761
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
index c9607db74b53487950d31f6a56d55f3e834556a0..a05e857d7111528ad7f21799e3825b9d3f488dd3 100644
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -23,6 +23,7 @@ namespace
// Arbitrarily enforce that types - even local variables' - declared
// with a size in bytes of over 2 GB will cause compilation failure.
constexpr size_t kMaxTypeSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
// Traverses intermediate tree to ensure that the shader does not
// exceed certain implementation-defined limits on the sizes of types.
@@ -31,7 +32,9 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
{
public:
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mDiagnostics(diagnostics),
+ mTotalPrivateVariablesSize(0)
{
ASSERT(diagnostics);
}
@@ -85,11 +88,37 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
asSymbol->getName());
return false;
}
+
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
+ variableType.getQualifier() == EvqGlobal ||
+ variableType.getQualifier() == EvqConst;
+ if (isPrivate)
+ {
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
+ }
}
return true;
}
+ void validateTotalPrivateVariableSize()
+ {
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
+ {
+ mDiagnostics->error(
+ TSourceLoc{},
+ "Total size of declared private variables exceeds implementation-defined limit",
+ "");
+ }
+ }
+
private:
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
{
@@ -198,6 +227,8 @@ class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
TDiagnostics *mDiagnostics;
std::vector<int> mLoopSymbolIds;
+
+ size_t mTotalPrivateVariablesSize;
};
} // namespace
@@ -208,6 +239,7 @@ bool ValidateTypeSizeLimitations(TIntermNode *root,
{
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
root->traverse(&validate);
+ validate.validateTotalPrivateVariableSize();
return diagnostics->numErrors() == 0;
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 7dc56cddbc63add1aca6fca3bfd031f3da8d04fc..64287af5834607f6819f1197e2eed1a56f712ffe 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -5271,11 +5271,12 @@ TEST_P(WebGLCompatibilityTest, ValidateArraySizes)
// fairly small array.
constexpr char kVSArrayOK[] =
R"(varying vec4 color;
-const int array_size = 1000;
+const int array_size = 500;
void main()
{
mat2 array[array_size];
- if (array[0][0][0] == 2.0)
+ mat2 array2[array_size];
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
color = vec4(0.0, 1.0, 0.0, 1.0);
else
color = vec4(1.0, 0.0, 0.0, 1.0);
@@ -5353,6 +5354,103 @@ void main()
EXPECT_EQ(0u, program);
}
+// Reject attempts to allocate too much private memory.
+// This is an implementation-defined limit - crbug.com/1431761.
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
+{
+ constexpr char kTooLargeGlobalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+vec4 array2[32769];
+
+void main()
+{
+ if (array[0].x + array[1].x == 0.)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32767];
+vec4 array2[32767];
+vec4 x, y, z;
+
+void main()
+{
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+void main()
+{
+ vec4 array2[32769];
+ if (array[0].x + array[1].x == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
+ R"(precision mediump float;
+
+// 1 MB / 16 bytes per vec4 = 65536
+vec4 array[32768];
+
+float f()
+{
+ vec4 array2[16384];
+ return array2[0].x;
+}
+
+float g()
+{
+ vec4 array3[16383];
+ return array3[0].x;
+}
+
+float h()
+{
+ vec4 value;
+ float value2
+ return value.x + value2;
+}
+
+void main()
+{
+ if (array[0].x + f() + g() + h() == 2.0)
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+})";
+
+ GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
+ EXPECT_EQ(0u, program);
+
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
+ EXPECT_EQ(0u, program);
+}
+
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)

View File

@@ -141,3 +141,9 @@ merge_m112_check_spdyproxyclientsocket_is_alive_after_write.patch
check_callback_availability_in.patch
m112_cherry_pick_libxml_cve_fix.patch
m112_fix_scopedobservation_uaf_in.patch
cherry-pick-48785f698b1c.patch
cherry-pick-675562695049.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 59b4a2c915caa192346f3fa342c5a2852a2f7b9b..1f3d5956b198ddf89cdf6951739ef68a29a74936 100644
--- a/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
+++ b/base/allocator/partition_allocator/shim/allocator_shim_unittest.cc
@@ -726,6 +726,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,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Arthur Sonzogni <arthursonzogni@chromium.org>
Date: Tue, 2 May 2023 09:40:37 +0000
Subject: Avoid buffer overflow read in HFSReadNextNonIgnorableCodePoint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Unicode codepoints goes beyond 0xFFFF.
It exists upper and lower case characters there: `𞤡 `vs `𞥃`.
The buffer overflow occurred when using the lookup table:
```
lower_case_table[codepoint >> 8]
```
Bug: 1425115
Fixed: 1425115
Change-Id: I679da02dbe570283a68176fbd3c0c620caa4f9ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4481260
Reviewed-by: Alexander Timin <altimin@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1138234}
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index a43c09317da96332584286fdb67284b2bedd753f..3a7cca6fad051816d6d018857c8039594c51ec65 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -775,7 +775,7 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
#elif BUILDFLAG(IS_APPLE)
// Mac OS X specific implementation of file string comparisons.
-// cf. http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties
+// cf. https://developer.apple.com/library/archive/technotes/tn/tn1150.html#UnicodeSubtleties
//
// "When using CreateTextEncoding to create a text encoding, you should set
// the TextEncodingBase to kTextEncodingUnicodeV2_0, set the
@@ -801,11 +801,12 @@ int FilePath::CompareIgnoreCase(StringPieceType string1,
// Ignored characters are mapped to zero.
//
// cf. downloadable file linked in
-// http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm
+// https://developer.apple.com/library/archive/technotes/tn/tn1150.html#Downloads
namespace {
-const UInt16 lower_case_table[] = {
+// clang-format off
+const UInt16 lower_case_table[11 * 256] = {
// High-byte indices ( == 0 iff no case mapping and no ignorables )
/* 0 */ 0x0100, 0x0200, 0x0000, 0x0300, 0x0400, 0x0500, 0x0000, 0x0000,
@@ -1191,11 +1192,12 @@ const UInt16 lower_case_table[] = {
/* F */ 0xFFF0, 0xFFF1, 0xFFF2, 0xFFF3, 0xFFF4, 0xFFF5, 0xFFF6, 0xFFF7,
0xFFF8, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF,
};
+// clang-format on
-// Returns the next non-ignorable codepoint within string starting from the
-// position indicated by index, or zero if there are no more.
-// The passed-in index is automatically advanced as the characters in the input
-// HFS-decomposed UTF-8 strings are read.
+// Returns the next non-ignorable codepoint within `string` starting from the
+// position indicated by `index`, or zero if there are no more.
+// The passed-in `index` is automatically advanced as the characters in the
+// input HFS-decomposed UTF-8 strings are read.
inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
size_t length,
size_t* index) {
@@ -1206,12 +1208,16 @@ inline base_icu::UChar32 HFSReadNextNonIgnorableCodepoint(const char* string,
CBU8_NEXT(reinterpret_cast<const uint8_t*>(string), *index, length,
codepoint);
DCHECK_GT(codepoint, 0);
- if (codepoint > 0) {
+
+ // Note: Here, there are no lower case conversion implemented in the
+ // Supplementary Multilingual Plane (codepoint > 0xFFFF).
+
+ if (codepoint > 0 && codepoint <= 0xFFFF) {
// Check if there is a subtable for this upper byte.
int lookup_offset = lower_case_table[codepoint >> 8];
if (lookup_offset != 0)
codepoint = lower_case_table[lookup_offset + (codepoint & 0x00FF)];
- // Note: codepoint1 may be again 0 at this point if the character was
+ // Note: `codepoint` may be again 0 at this point if the character was
// an ignorable.
}
}
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc
index 3cfdcbe445c1f6e0d66e3798927131f94759fb3c..08c3e75b7e1ad55f5f81aed80f80081115f8f49c 100644
--- a/base/files/file_path_unittest.cc
+++ b/base/files/file_path_unittest.cc
@@ -1195,6 +1195,13 @@ TEST_F(FilePathTest, CompareIgnoreCase) {
{{FPL("K\u0301U\u032DO\u0304\u0301N"), FPL("\u1E31\u1E77\u1E53n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0301n"), FPL("\u1E30\u1E76\u1E52n")}, 0},
{{FPL("k\u0301u\u032Do\u0304\u0302n"), FPL("\u1E30\u1E76\u1E52n")}, 1},
+
+ // Codepoints > 0xFFFF
+ // Here, we compare the `Adlam Letter Shu` in its capital and small version.
+ {{FPL("\U0001E921"), FPL("\U0001E943")}, -1},
+ {{FPL("\U0001E943"), FPL("\U0001E921")}, 1},
+ {{FPL("\U0001E921"), FPL("\U0001E921")}, 0},
+ {{FPL("\U0001E943"), FPL("\U0001E943")}, 0},
#endif
};

View File

@@ -0,0 +1,142 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Mon, 15 May 2023 03:21:49 +0000
Subject: Return after ReadyCommitNavigation call in CommitErrorPage if it
deletes NavigationRequest
NavigationRequest::ReadyToCommitNavigation() can cause deletion of the
NavigationRequest, so callers should check for that possibility after
calling the function. A caller in CommitErrorPage is missing that
check, which this CL adds, along with a regression test.
(cherry picked from commit 42db806805ef2be64ee92803d3a784631b2a7df0)
Bug: 1444360
Change-Id: I3964da4909a6709b7730d25d6497b19c098f4f21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4520493
Commit-Queue: Charlie Reis <creis@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1143298}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4531446
Reviewed-by: Prudhvikumar Bommana <pbommana@google.com>
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Commit-Queue: Prudhvikumar Bommana <pbommana@google.com>
Owners-Override: Prudhvikumar Bommana <pbommana@google.com>
Cr-Commit-Position: refs/branch-heads/5735@{#607}
Cr-Branched-From: 2f562e4ddbaf79a3f3cb338b4d1bd4398d49eb67-refs/heads/main@{#1135570}
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index fd95d91a9a4efbfbbcfb117d9f2129b1b1c95011..c3f1bb989c30bf00750404995d080c3b8ee0e1c6 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -5034,7 +5034,13 @@ void NavigationRequest::CommitErrorPage(
}
}
+ base::WeakPtr<NavigationRequest> weak_self(weak_factory_.GetWeakPtr());
ReadyToCommitNavigation(true /* is_error */);
+ // The caller above might result in the deletion of `this`. Return immediately
+ // if so.
+ if (!weak_self) {
+ return;
+ }
PopulateDocumentTokenForCrossDocumentNavigation();
// Use a separate cache shard, and no cookies, for error pages.
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc
index 1213eb485a25a183ca23643941ae97ee6cfb596f..837af410e31d90769cb7e5d0f9c0bb9abf3035df 100644
--- a/content/browser/renderer_host/navigation_request_browsertest.cc
+++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -44,6 +44,7 @@
#include "content/public/test/prerender_test_util.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_service.mojom.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
@@ -4032,4 +4033,84 @@ IN_PROC_BROWSER_TEST_P(NavigationRequestMPArchBrowserTest,
}
}
+// Tests that when trying to commit an error page for a failed navigation, but
+// the renderer process of the, the navigation won't commit and won't crash.
+// Regression test for https://crbug.com/1444360.
+IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest,
+ RendererCrashedBeforeCommitErrorPage) {
+ // Navigate to `url_a` first.
+ GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ ASSERT_TRUE(NavigateToURL(shell(), url_a));
+
+ // Set up an URLLoaderInterceptor which will cause future navigations to fail.
+ auto url_loader_interceptor = std::make_unique<URLLoaderInterceptor>(
+ base::BindRepeating([](URLLoaderInterceptor::RequestParams* params) {
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_NOT_IMPLEMENTED;
+ params->client->OnComplete(status);
+ return true;
+ }));
+
+ // Do a navigation to `url_b1` that will fail and commit an error page. This
+ // is important so that the next error page navigation won't need to create a
+ // speculative RenderFrameHost (unless RenderDocument is enabled) and won't
+ // get cancelled earlier than commit time due to speculative RFH deletion.
+ GURL url_b1(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ EXPECT_FALSE(NavigateToURL(shell(), url_b1));
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+ EXPECT_TRUE(
+ shell()->web_contents()->GetPrimaryMainFrame()->IsErrorDocument());
+
+ // For the next navigation, set up a throttle that will be used to wait for
+ // WillFailRequest() and then defer the navigation, so that we can crash the
+ // error page process first.
+ TestNavigationThrottleInstaller installer(
+ shell()->web_contents(),
+ NavigationThrottle::PROCEED /* will_start_result */,
+ NavigationThrottle::PROCEED /* will_redirect_result */,
+ NavigationThrottle::DEFER /* will_fail_result */,
+ NavigationThrottle::PROCEED /* will_process_result */,
+ NavigationThrottle::PROCEED /* will_commit_without_url_loader_result */);
+
+ // Start a navigation to `url_b2` that will also fail, but before it commits
+ // an error page, cause the error page process to crash.
+ GURL url_b2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ TestNavigationManager manager(shell()->web_contents(), url_b2);
+ shell()->LoadURL(url_b2);
+ EXPECT_TRUE(manager.WaitForRequestStart());
+
+ // Resume the navigation and wait for WillFailRequest(). After this point, we
+ // will have picked the final RenderFrameHost & RenderProcessHost for the
+ // failed navigation.
+ manager.ResumeNavigation();
+ installer.WaitForThrottleWillFail();
+
+ // Kill the error page process. This will cause for the navigation to `url_b2`
+ // to return early in `NavigationRequest::ReadyToCommitNavigation()` and not
+ // commit a new error page.
+ RenderProcessHost* process_to_kill =
+ manager.GetNavigationHandle()->GetRenderFrameHost()->GetProcess();
+ ASSERT_TRUE(process_to_kill->IsInitializedAndNotDead());
+ {
+ // Trigger a renderer kill by calling DoSomething() which will cause a bad
+ // message to be reported.
+ RenderProcessHostBadIpcMessageWaiter kill_waiter(process_to_kill);
+ mojo::Remote<mojom::TestService> service;
+ process_to_kill->BindReceiver(service.BindNewPipeAndPassReceiver());
+ service->DoSomething(base::DoNothing());
+ EXPECT_EQ(bad_message::RPH_MOJO_PROCESS_ERROR, kill_waiter.Wait());
+ }
+ ASSERT_FALSE(process_to_kill->IsInitializedAndNotDead());
+
+ // Resume the navigation, which won't commit.
+ if (!ShouldCreateNewHostForAllFrames()) {
+ installer.navigation_throttle()->ResumeNavigation();
+ }
+ EXPECT_TRUE(manager.WaitForNavigationFinished());
+ EXPECT_FALSE(WaitForLoadStop(shell()->web_contents()));
+
+ // The tab stayed at `url_b1` as the `url_b2` navigation didn't commit.
+ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_b1);
+}
+
} // namespace content

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 cebe56b9e79cbe0e5a58f73e68faf1b93b17ce5c..3748f8119bf1d4f37635bdb4fb87d825881de7f0 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -3888,6 +3888,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 5ed4f0223346b01d83cc04c8cda6c0e92e1a72e3..4a1543d1751cc817a511594d0123deacc0e61ebb 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
@@ -2859,6 +2859,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';
@@ -3600,6 +3614,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 1e9148687f6871dff8a394cce53771e443775679..37630dc2f0a6365bbf33e765f4d126e2962fbb2a 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 54a8dfdd931a22c5acfe3613204ea3a89b842d13..1e76a1a655d0f9de1dd218ad4025a6210ceafc57 100644
--- a/ui/gl/swap_chain_presenter.cc
+++ b/ui/gl/swap_chain_presenter.cc
@@ -1698,10 +1698,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 6194c0c2da8292b8229972eadf9fd6fa56ef0c86..b8372a6281ddcaf0990f55856a9e815fb9d78195 100644
--- a/mojo/core/ipcz_driver/mojo_message.cc
+++ b/mojo/core/ipcz_driver/mojo_message.cc
@@ -112,23 +112,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

@@ -25,5 +25,9 @@
"src/electron/patches/webrtc": "src/third_party/webrtc",
"src/electron/patches/skia": "src/third_party/skia"
"src/electron/patches/skia": "src/third_party/skia",
"src/electron/patches/dawn": "src/third_party/dawn",
"src/electron/patches/pdfium": "src/third_party/pdfium"
}

1
patches/dawn/.patches Normal file
View File

@@ -0,0 +1 @@
change_d3d12_descriptor_allocator_to_invalidate_submitted_descriptors.patch

View File

@@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brandon Jones <brandon1.jones@intel.com>
Date: Fri, 5 May 2023 18:02:42 +0000
Subject: Change D3D12 Descriptor Allocator To Invalidate Submitted Descriptors
Changes D3D12 descriptor allocator to invalidate existing descriptors
after the descriptor heap was submitted for use. This fixes a
synchonization issue where stale descriptors were seen as valid because
command list execution ran long.
Bug: dawn:1701
Bug: chromium:1442263
No-Try: true
Change-Id: Ibfd450b3be6cf91d66e8dce4ffd19ecf1a37f7f5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com>
(cherry picked from commit df6cb236493da101dad79fe50d4e6df0d5d1e915)
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/131508
Kokoro: Austin Eng <enga@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
index fe99a63ac9d2d082c2c23eb7940a733a9d13846a..aedb28ad58a0a972879f07a6037499f901fcf04a 100644
--- a/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.cpp
@@ -237,9 +237,11 @@ bool ShaderVisibleDescriptorAllocator::IsLastShaderVisibleHeapInLRUForTesting()
bool ShaderVisibleDescriptorAllocator::IsAllocationStillValid(
const GPUDescriptorHeapAllocation& allocation) const {
- // Consider valid if allocated for the pending submit and the shader visible heaps
- // have not switched over.
- return (allocation.GetLastUsageSerial() > mDevice->GetCompletedCommandSerial() &&
+ // Descriptor allocations are only valid for the serial they were created for and are
+ // re-allocated every submit. For this reason, we view any descriptors allocated prior to the
+ // pending submit as invalid. We must also verify the descriptor heap has not switched (because
+ // a larger descriptor heap was needed).
+ return (allocation.GetLastUsageSerial() == mDevice->GetPendingCommandSerial() &&
allocation.GetHeapSerial() == mHeapSerial);
}

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 4cda2135433b07d641d773f184034b0f3dee7e58..f9a8550da29e7a7afca757167af257d95a67bd9f 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -400,7 +400,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:
@@ -408,7 +410,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;
@@ -438,7 +442,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().
}
@@ -451,7 +455,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 480da52d7a65538dee190e2a609215f9c424bb38..b1ac3d9e8ac29e9433330ff86df7ef4b71a3fabd 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.h
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
@@ -64,7 +64,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 dde76521a7c15070c1245938063830a003986a69..4cda2135433b07d641d773f184034b0f3dee7e58 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -339,31 +339,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();
}
}
@@ -411,10 +422,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

@@ -10,3 +10,10 @@ force_cppheapcreateparams_to_be_noncopyable.patch
chore_allow_customizing_microtask_policy_per_context.patch
cherry-pick-c605df24af3c.patch
cherry-pick-f4b66ae451c2.patch
cherry-pick-2c8a019f39d2.patch
cherry-pick-bb90b9cfcbca.patch
merged_ic_fix_store_handler_selection_for_arguments_objects.patch
cherry-pick-73af1a19a901.patch
cherry-pick-3b0607d14060.patch
cherry-pick-9c6dfc733fce.patch
cherry-pick-2e76270cf65e.patch

View File

@@ -0,0 +1,300 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo <syg@chromium.org>
Date: Wed, 26 Apr 2023 10:56:03 -0700
Subject: Fix clobbered register in global Unicode special case
Bug: chromium:1439691
Change-Id: I53f22f484b226b5ad3eb9ffef8a9f44fe962beba
Fixed: chromium:1439691
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4477629
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#87288}
diff --git a/src/regexp/arm/regexp-macro-assembler-arm.cc b/src/regexp/arm/regexp-macro-assembler-arm.cc
index 2658068b6f94b97f024b1400c8c0b20eefdc5143..5de110c8495ef5bd261df92ca8f459c5f0cc7e5b 100644
--- a/src/regexp/arm/regexp-macro-assembler-arm.cc
+++ b/src/regexp/arm/regexp-macro-assembler-arm.cc
@@ -877,19 +877,18 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
__ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
__ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r0 to initialize registers with its value in the next run.
- __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r4: capture start index
__ cmp(current_input_offset(), r4);
// Not a zero-length match, restart.
- __ b(ne, &load_char_start_regexp);
+ __ b(ne, &reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ cmp(current_input_offset(), Operand::Zero());
__ b(eq, &exit_label_);
@@ -901,6 +900,11 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r0, Operand(SUCCESS));
diff --git a/src/regexp/ia32/regexp-macro-assembler-ia32.cc b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
index 600234542042ce9a06ceb3b415fece83f6f271bf..6c3df5da7d6c28619902b20419c9cf437325c1d1 100644
--- a/src/regexp/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/regexp/ia32/regexp-macro-assembler-ia32.cc
@@ -915,19 +915,18 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ add(Operand(ebp, kRegisterOutput),
Immediate(num_saved_registers_ * kSystemPointerSize));
- // Prepare eax to initialize registers with its value in the next run.
- __ mov(eax, Operand(ebp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), ebx);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// edx: capture start index
__ cmp(edi, edx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// edi (offset from the end) is zero if we already reached the end.
__ test(edi, edi);
__ j(zero, &exit_label_, Label::kNear);
@@ -941,6 +940,12 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
}
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+
+ __ bind(&reload_string_start_minus_one);
+ // Prepare eax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ mov(eax, Operand(ebp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ mov(eax, Immediate(SUCCESS));
diff --git a/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
index 35fd95bd0f2d210419b4057ced6e16ffd5aec051..d5c52b4134ccbfecef85328e181dae1bbda7bf63 100644
--- a/src/regexp/loong64/regexp-macro-assembler-loong64.cc
+++ b/src/regexp/loong64/regexp-macro-assembler-loong64.cc
@@ -850,18 +850,17 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ Add_d(a2, a2, num_saved_registers_ * kIntSize);
__ St_d(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -874,6 +873,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
index 456e166adefc72b7bcaa9245798f3885c2a4c2e7..6ee4c709cf96f68a32a0b3c1ebdc42817293bf29 100644
--- a/src/regexp/mips64/regexp-macro-assembler-mips64.cc
+++ b/src/regexp/mips64/regexp-macro-assembler-mips64.cc
@@ -898,19 +898,18 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ Daddu(a2, a2, num_saved_registers_ * kIntSize);
__ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// t3: capture start index
// Not a zero-length match, restart.
- __ Branch(
- &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
+ Operand(t3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
Operand(zero_reg));
@@ -922,6 +921,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(v0, Operand(SUCCESS));
diff --git a/src/regexp/riscv/regexp-macro-assembler-riscv.cc b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
index c8f3eb551e05805003d30a1786acdd9aab96d906..7f79b1e02b145e56ac49d231f31555039c959c05 100644
--- a/src/regexp/riscv/regexp-macro-assembler-riscv.cc
+++ b/src/regexp/riscv/regexp-macro-assembler-riscv.cc
@@ -869,18 +869,17 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
__ AddWord(a2, a2, num_saved_registers_ * kIntSize);
__ StoreWord(a2, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare a0 to initialize registers with its value in the next run.
- __ LoadWord(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// s3: capture start index
// Not a zero-length match, restart.
- __ Branch(&load_char_start_regexp, ne, current_input_offset(),
+ __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
Operand(s3));
// Offset from the end is zero if we already reached the end.
__ Branch(&exit_label_, eq, current_input_offset(),
@@ -893,6 +892,12 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare a0 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadWord(a0,
+ MemOperand(frame_pointer(), kStringStartMinusOneOffset));
+
__ Branch(&load_char_start_regexp);
} else {
__ li(a0, Operand(SUCCESS));
diff --git a/src/regexp/s390/regexp-macro-assembler-s390.cc b/src/regexp/s390/regexp-macro-assembler-s390.cc
index a61bc379ba6c265ecb0c5cd7aa8d7a2e35ca6c1e..de184b95862e7f2e64d69cff6b60d866eb212f36 100644
--- a/src/regexp/s390/regexp-macro-assembler-s390.cc
+++ b/src/regexp/s390/regexp-macro-assembler-s390.cc
@@ -947,19 +947,18 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
__ AddS64(r4, Operand(num_saved_registers_ * kIntSize));
__ StoreU64(r4, MemOperand(frame_pointer(), kRegisterOutput));
- // Prepare r2 to initialize registers with its value in the next run.
- __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), r4);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// r6: capture start index
__ CmpS64(current_input_offset(), r6);
// Not a zero-length match, restart.
- __ bne(&load_char_start_regexp);
+ __ bne(&reload_string_start_minus_one);
// Offset from the end is zero if we already reached the end.
__ CmpS64(current_input_offset(), Operand::Zero());
__ beq(&exit_label_);
@@ -970,6 +969,11 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare r2 to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ LoadU64(r2, MemOperand(frame_pointer(), kStringStartMinusOne));
+
__ b(&load_char_start_regexp);
} else {
__ mov(r2, Operand(SUCCESS));
diff --git a/src/regexp/x64/regexp-macro-assembler-x64.cc b/src/regexp/x64/regexp-macro-assembler-x64.cc
index 89fd2e34f1296113c43f16896d8f35d741782709..7c59534aa46c4c1c6fed151d7dad13070d133f47 100644
--- a/src/regexp/x64/regexp-macro-assembler-x64.cc
+++ b/src/regexp/x64/regexp-macro-assembler-x64.cc
@@ -951,19 +951,18 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ addq(Operand(rbp, kRegisterOutput),
Immediate(num_saved_registers_ * kIntSize));
- // Prepare rax to initialize registers with its value in the next run.
- __ movq(rax, Operand(rbp, kStringStartMinusOne));
-
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), kScratchRegister);
+ Label reload_string_start_minus_one;
+
if (global_with_zero_length_check()) {
// Special case for zero-length matches.
// rdx: capture start index
__ cmpq(rdi, rdx);
// Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
+ __ j(not_equal, &reload_string_start_minus_one);
// rdi (offset from the end) is zero if we already reached the end.
__ testq(rdi, rdi);
__ j(zero, &exit_label_, Label::kNear);
@@ -978,6 +977,11 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
}
+ __ bind(&reload_string_start_minus_one);
+ // Prepare rax to initialize registers with its value in the next run.
+ // Must be immediately before the jump to avoid clobbering.
+ __ movq(rax, Operand(rbp, kStringStartMinusOne));
+
__ jmp(&load_char_start_regexp);
} else {
__ Move(rax, SUCCESS);
diff --git a/test/mjsunit/regress/regress-crbug-1439691.js b/test/mjsunit/regress/regress-crbug-1439691.js
new file mode 100644
index 0000000000000000000000000000000000000000..6c55835535ab4f42ef0446abf863986962df9e9b
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-1439691.js
@@ -0,0 +1,7 @@
+// 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.
+
+function f0() {
+}
+/(?!(a))\1/gudyi[Symbol.replace]("f\uD83D\uDCA9ba\u2603", f0);

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 9d1e3a95746b47b99c15f18ec593549d79e10b8c..c7e98e55763aba2d64f4070e25759489f850f589 100644
--- a/src/strings/string-builder.cc
+++ b/src/strings/string-builder.cc
@@ -306,12 +306,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 93939fa4702922f58e8e5bcc019e569f42ab198e..1190b3dedfabee414fb49038e31b3cf2bbce68ee 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -1816,14 +1816,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 39cc83aacb5caf0791ce70212695f5016a22f274..b3f7db7bd984e8524689c3060bfd0674840fa63b 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -243,27 +243,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(
- Handle<JSObject>::cast(it->GetReceiver()))) {
- RETURN_FAILURE(
- isolate, GetShouldThrow(isolate, should_throw),
- NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
- }
- return Just(true);
-}
-
namespace {
bool HasExcludedProperty(
@@ -3643,7 +3622,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;
@@ -4072,17 +4051,16 @@ Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
Handle<Object> value,
Maybe<ShouldThrow> should_throw) {
DCHECK(it->GetReceiver()->IsJSObject());
- MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
Isolate* isolate = receiver->GetIsolate();
- 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>());
@@ -4708,19 +4686,42 @@ 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(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 ff96bd4be2ff8d2fe03f75b6bca35a744e2084af..5e7326eb1c99115829c358cd4069e1f6835f972b 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,
@@ -545,6 +539,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 44b8f9502e32a9a6fbbe60ebc5f8e0d184411b8f..782698bd7c488f5570288119e49784e16a93ddd2 100644
--- a/src/objects/lookup-inl.h
+++ b/src/objects/lookup-inl.h
@@ -167,7 +167,7 @@ Handle<Name> PropertyKey::GetName(Isolate* isolate) {
}
Handle<Name> LookupIterator::name() const {
- DCHECK(!IsElement(*holder_));
+ DCHECK_IMPLIES(!holder_.is_null(), !IsElement(*holder_));
return name_;
}
@@ -257,6 +257,7 @@ void LookupIterator::UpdateProtector() {
}
InternalIndex LookupIterator::descriptor_number() const {
+ DCHECK(!holder_.is_null());
DCHECK(!IsElement(*holder_));
DCHECK(has_property_);
DCHECK(holder_->HasFastProperties(isolate_));
@@ -264,6 +265,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_));
@@ -278,13 +280,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 7c6f6c4a350fec92a3cc0a48a14c0b92f8d6021d..ce1502b859c0cce77fc054488e401ac82a073a7d 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),
@@ -901,6 +902,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());
@@ -934,6 +936,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());
@@ -980,6 +983,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_));
@@ -987,6 +991,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 9adee79b3028c53e6481a07316d74aed616f01bd..ef90316295c98d51b61c118cf331731f991d93d0 100644
--- a/src/objects/lookup.h
+++ b/src/objects/lookup.h
@@ -214,11 +214,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);
@@ -278,12 +273,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 b3f7db7bd984e8524689c3060bfd0674840fa63b..8cc8af6c221a90cc6a6201faa46738ec80ffccdb 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -3633,10 +3633,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 782698bd7c488f5570288119e49784e16a93ddd2..35eaed8ffbc23248c33230868f428bc192c5b790 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 ef90316295c98d51b61c118cf331731f991d93d0..5d2d926b7e3dcecf8529f7d1c1e919033d9faa7f 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 01d826c43bf9ec8bb28aba0e59fd3fa8f5700bac..b57c68073e401bb34796689013213791d40af10a 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -2668,11 +2668,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:
@@ -2709,6 +2706,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

@@ -0,0 +1,362 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Thu, 27 Apr 2023 11:11:32 +0200
Subject: Merged: [api] Fix v8::Object::SetAccessorProperty
... by using JavaScript spec compliant JSReceiver::DefineOwnProperty.
Drive-by:
- cleanup comments in include/v8-object.h, insert links to
respective pages of https://tc39.es/ecma262/ when referencing spec,
- rename JSObject::DefineAccessor() to
JSObject::DefineOwnAccessorIgnoreAttributes().
Bug: chromium:1433211
(cherry picked from commit b8020e1973d7d3a50b17c076cd948f079e59f9e5)
Change-Id: Ia4e0389e99b5a79987f59ca2a11ee7867b0c97e2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4502585
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/11.2@{#47}
Cr-Branched-From: 755511a138609ac5939449a8ac615c15603a4454-refs/heads/11.2.214@{#1}
Cr-Branched-From: e6b1ccefb0f0f1ff8d310578878130dc53d73749-refs/heads/main@{#86014}
diff --git a/include/v8-object.h b/include/v8-object.h
index d7332ba0c88d12e8086f56117631dfb3e1e514b4..dfeda2d39431d481dbeab6698c3d3e7f02a1b19c 100644
--- a/include/v8-object.h
+++ b/include/v8-object.h
@@ -247,13 +247,16 @@ class V8_EXPORT Object : public Value {
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
Local<Value> value);
- // Implements CreateDataProperty (ECMA-262, 7.3.4).
- //
- // Defines a configurable, writable, enumerable property with the given value
- // on the object unless the property already exists and is not configurable
- // or the object is not extensible.
- //
- // Returns true on success.
+ /**
+ * Implements CreateDataProperty(O, P, V), see
+ * https://tc39.es/ecma262/#sec-createdataproperty.
+ *
+ * Defines a configurable, writable, enumerable property with the given value
+ * on the object unless the property already exists and is not configurable
+ * or the object is not extensible.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> CreateDataProperty(Local<Context> context,
Local<Name> key,
Local<Value> value);
@@ -261,29 +264,35 @@ class V8_EXPORT Object : public Value {
uint32_t index,
Local<Value> value);
- // Implements DefineOwnProperty.
- //
- // In general, CreateDataProperty will be faster, however, does not allow
- // for specifying attributes.
- //
- // Returns true on success.
+ /**
+ * Implements [[DefineOwnProperty]] for data property case, see
+ * https://tc39.es/ecma262/#table-essential-internal-methods.
+ *
+ * In general, CreateDataProperty will be faster, however, does not allow
+ * for specifying attributes.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
Local<Context> context, Local<Name> key, Local<Value> value,
PropertyAttribute attributes = None);
- // Implements Object.DefineProperty(O, P, Attributes), see Ecma-262 19.1.2.4.
- //
- // The defineProperty function is used to add an own property or
- // update the attributes of an existing own property of an object.
- //
- // Both data and accessor descriptors can be used.
- //
- // In general, CreateDataProperty is faster, however, does not allow
- // for specifying attributes or an accessor descriptor.
- //
- // The PropertyDescriptor can change when redefining a property.
- //
- // Returns true on success.
+ /**
+ * Implements Object.defineProperty(O, P, Attributes), see
+ * https://tc39.es/ecma262/#sec-object.defineproperty.
+ *
+ * The defineProperty function is used to add an own property or
+ * update the attributes of an existing own property of an object.
+ *
+ * Both data and accessor descriptors can be used.
+ *
+ * In general, CreateDataProperty is faster, however, does not allow
+ * for specifying attributes or an accessor descriptor.
+ *
+ * The PropertyDescriptor can change when redefining a property.
+ *
+ * Returns true on success.
+ */
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
Local<Context> context, Local<Name> key, PropertyDescriptor& descriptor);
@@ -302,14 +311,15 @@ class V8_EXPORT Object : public Value {
Local<Context> context, Local<Value> key);
/**
- * Returns Object.getOwnPropertyDescriptor as per ES2016 section 19.1.2.6.
+ * Implements Object.getOwnPropertyDescriptor(O, P), see
+ * https://tc39.es/ecma262/#sec-object.getownpropertydescriptor.
*/
V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor(
Local<Context> context, Local<Name> key);
/**
- * Object::Has() calls the abstract operation HasProperty(O, P) described
- * in ECMA-262, 7.3.10. Has() returns
+ * Object::Has() calls the abstract operation HasProperty(O, P), see
+ * https://tc39.es/ecma262/#sec-hasproperty. Has() returns
* true, if the object has the property, either own or on the prototype chain.
* Interceptors, i.e., PropertyQueryCallbacks, are called if present.
*
@@ -347,7 +357,7 @@ class V8_EXPORT Object : public Value {
void SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter = Local<Function>(),
- PropertyAttribute attribute = None,
+ PropertyAttribute attributes = None,
AccessControl settings = DEFAULT);
/**
diff --git a/src/api/api-natives.cc b/src/api/api-natives.cc
index d0b298723423e9ad4d151c463dcdde09d2400336..9f664a755e4b04d935d29b1be796a81ac3fe0c07 100644
--- a/src/api/api-natives.cc
+++ b/src/api/api-natives.cc
@@ -96,10 +96,10 @@ MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate,
Handle<CodeT> trampoline = BUILTIN_CODE(isolate, DebugBreakTrampoline);
Handle<JSFunction>::cast(setter)->set_code(*trampoline);
}
- RETURN_ON_EXCEPTION(
- isolate,
- JSObject::DefineAccessor(object, name, getter, setter, attributes),
- Object);
+ RETURN_ON_EXCEPTION(isolate,
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, setter, attributes),
+ Object);
return object;
}
diff --git a/src/api/api.cc b/src/api/api.cc
index d790bc0fd1b42a6b8107712d5c171751f83e5727..fbdbe4b5c7166e4dc1b2ad7b01aa911beed7f69c 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -5061,7 +5061,7 @@ Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
Local<Function> setter,
- PropertyAttribute attribute,
+ PropertyAttribute attributes,
AccessControl settings) {
// TODO(verwaest): Remove |settings|.
DCHECK_EQ(v8::DEFAULT, settings);
@@ -5073,9 +5073,20 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
if (setter_i.is_null()) setter_i = i_isolate->factory()->null_value();
- i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
- v8::Utils::OpenHandle(*name), getter_i, setter_i,
- static_cast<i::PropertyAttributes>(attribute));
+
+ i::PropertyDescriptor desc;
+ desc.set_enumerable(!(attributes & v8::DontEnum));
+ desc.set_configurable(!(attributes & v8::DontDelete));
+ desc.set_get(getter_i);
+ desc.set_set(setter_i);
+
+ i::Handle<i::Name> name_i = v8::Utils::OpenHandle(*name);
+ // DefineOwnProperty might still throw if the receiver is a JSProxy and it
+ // might fail if the receiver is non-extensible or already has this property
+ // as non-configurable.
+ Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
+ i_isolate, self, name_i, &desc, Just(i::kDontThrow));
+ USE(success);
}
Maybe<bool> Object::SetNativeDataProperty(
diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc
index 3f5050e824c09ee2577dbd8471ac6b1bcc20755e..f7fdf90f0baeb3dd3516c565bb5e05fc7e8da550 100644
--- a/src/init/bootstrapper.cc
+++ b/src/init/bootstrapper.cc
@@ -631,7 +631,9 @@ V8_NOINLINE void SimpleInstallGetterSetter(Isolate* isolate,
Handle<JSFunction> setter =
SimpleCreateFunction(isolate, setter_name, call_setter, 1, true);
- JSObject::DefineAccessor(base, name, getter, setter, DONT_ENUM).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, name, getter, setter,
+ DONT_ENUM)
+ .Check();
}
void SimpleInstallGetterSetter(Isolate* isolate, Handle<JSObject> base,
@@ -655,7 +657,8 @@ V8_NOINLINE Handle<JSFunction> SimpleInstallGetter(Isolate* isolate,
Handle<Object> setter = isolate->factory()->undefined_value();
- JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM)
+ JSObject::DefineOwnAccessorIgnoreAttributes(base, property_name, getter,
+ setter, DONT_ENUM)
.Check();
return getter;
diff --git a/src/objects/js-objects.cc b/src/objects/js-objects.cc
index 59c9f966036fdd3640b06b2d6962fc9994ab3c31..39cc83aacb5caf0791ce70212695f5016a22f274 100644
--- a/src/objects/js-objects.cc
+++ b/src/objects/js-objects.cc
@@ -1519,7 +1519,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
? desc->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
+ JSObject::DefineOwnAccessorIgnoreAttributes(it, getter, setter,
+ desc->ToAttributes());
if (result.is_null()) return Nothing<bool>();
}
}
@@ -1703,8 +1704,8 @@ Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
: current->has_set()
? current->set()
: Handle<Object>::cast(isolate->factory()->null_value()));
- MaybeHandle<Object> result =
- JSObject::DefineAccessor(it, getter, setter, attrs);
+ MaybeHandle<Object> result = JSObject::DefineOwnAccessorIgnoreAttributes(
+ it, getter, setter, attrs);
if (result.is_null()) return Nothing<bool>();
}
}
@@ -4638,22 +4639,19 @@ bool JSObject::HasEnumerableElements() {
UNREACHABLE();
}
-MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
+ Handle<Object> setter, PropertyAttributes attributes) {
Isolate* isolate = object->GetIsolate();
PropertyKey key(isolate, name);
LookupIterator it(isolate, object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
- return DefineAccessor(&it, getter, setter, attributes);
+ return DefineOwnAccessorIgnoreAttributes(&it, getter, setter, attributes);
}
-MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes) {
+MaybeHandle<Object> JSObject::DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes) {
Isolate* isolate = it->isolate();
it->UpdateProtector();
diff --git a/src/objects/js-objects.h b/src/objects/js-objects.h
index 06489c2b7bae61ecadbd8f020060e86ef50e11b6..ff96bd4be2ff8d2fe03f75b6bca35a744e2084af 100644
--- a/src/objects/js-objects.h
+++ b/src/objects/js-objects.h
@@ -531,13 +531,14 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it);
// Defines an AccessorPair property on the given object.
- V8_EXPORT_PRIVATE static MaybeHandle<Object> DefineAccessor(
- Handle<JSObject> object, Handle<Name> name, Handle<Object> getter,
- Handle<Object> setter, PropertyAttributes attributes);
- static MaybeHandle<Object> DefineAccessor(LookupIterator* it,
- Handle<Object> getter,
- Handle<Object> setter,
- PropertyAttributes attributes);
+ V8_EXPORT_PRIVATE static MaybeHandle<Object>
+ DefineOwnAccessorIgnoreAttributes(Handle<JSObject> object, Handle<Name> name,
+ Handle<Object> getter,
+ Handle<Object> setter,
+ PropertyAttributes attributes);
+ static MaybeHandle<Object> DefineOwnAccessorIgnoreAttributes(
+ LookupIterator* it, Handle<Object> getter, Handle<Object> setter,
+ PropertyAttributes attributes);
// Defines an AccessorInfo property on the given object.
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> SetAccessor(
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index 5255ee26807ab13e93935b6c6d513184a12da7cd..f10e4649c6d078c3120063d53e54f4126b2d2fd5 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -1109,7 +1109,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
auto attrs = PropertyAttributesFromInt(args.smi_value_at(4));
RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::DefineAccessor(obj, name, getter, setter, attrs));
+ isolate, JSObject::DefineOwnAccessorIgnoreAttributes(obj, name, getter,
+ setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1215,8 +1216,8 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, getter,
- isolate->factory()->null_value(), attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, getter, isolate->factory()->null_value(), attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1360,8 +1361,8 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) {
RETURN_FAILURE_ON_EXCEPTION(
isolate,
- JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
- setter, attrs));
+ JSObject::DefineOwnAccessorIgnoreAttributes(
+ object, name, isolate->factory()->null_value(), setter, attrs));
return ReadOnlyRoots(isolate).undefined_value();
}
diff --git a/src/sandbox/testing.cc b/src/sandbox/testing.cc
index fead4aa222ceb81d76f6dfec7e7797e337e7ba94..aab72a18015bf7ac1d0949e9497e85d9d089b4b8 100644
--- a/src/sandbox/testing.cc
+++ b/src/sandbox/testing.cc
@@ -156,7 +156,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object,
Handle<String> property_name = factory->NewStringFromAsciiChecked(name);
Handle<JSFunction> getter = CreateFunc(isolate, func, property_name, false);
Handle<Object> setter = factory->null_value();
- JSObject::DefineAccessor(object, property_name, getter, setter, FROZEN);
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, property_name, getter,
+ setter, FROZEN);
}
void InstallFunction(Isolate* isolate, Handle<JSObject> holder,
diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
index c012e62016aca3a83975cd91216860ea9dc3d311..4c3402c7deec768931d07488cbbb79a0a7a7dd23 100644
--- a/test/cctest/test-code-stub-assembler.cc
+++ b/test/cctest/test-code-stub-assembler.cc
@@ -1178,7 +1178,9 @@ void AddProperties(Handle<JSObject> object, Handle<Name> names[],
Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value);
Handle<Object> getter(pair->getter(), isolate);
Handle<Object> setter(pair->setter(), isolate);
- JSObject::DefineAccessor(object, names[i], getter, setter, NONE).Check();
+ JSObject::DefineOwnAccessorIgnoreAttributes(object, names[i], getter,
+ setter, NONE)
+ .Check();
} else {
JSObject::AddProperty(isolate, object, names[i], value, NONE);
}

View File

@@ -0,0 +1,122 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Igor Sheludko <ishell@chromium.org>
Date: Fri, 2 Jun 2023 18:13:01 +0200
Subject: Merged: [ic] Fix store handler selection for arguments objects
Drive-by: fix printing of handlers in --trace-feedback-updates mode.
(cherry picked from commit e144f3b71e64e01d6ffd247eb15ca1ff56f6287b)
Bug: chromium:1450481
Change-Id: Ifbb97d694b8520584df0610aad30805713b29c00
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4584889
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/branch-heads/10.9@{#32}
Cr-Branched-From: 8ade6bf1fa237ad30dd9a05cc6ffe548131699e8-refs/heads/10.9.194@{#1}
Cr-Branched-From: 9ff2515271f11cab783f0e82678ae0b925d77dd0-refs/heads/main@{#84164}
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index b763468f58f8f0be294af50188dd69b99c9428dc..e4e206f2b52095c95ac4c667f32f0620c753967c 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -1324,8 +1324,18 @@ void FeedbackNexus::Print(std::ostream& os) {
case FeedbackSlotKind::kSetKeyedStrict: {
os << InlineCacheState2String(ic_state());
if (ic_state() == InlineCacheState::MONOMORPHIC) {
- os << "\n " << Brief(GetFeedback()) << ": ";
- StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(), os);
+ 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);
+ }
} else if (ic_state() == InlineCacheState::POLYMORPHIC) {
WeakFixedArray array =
WeakFixedArray::cast(GetFeedback().GetHeapObject());
diff --git a/src/ic/handler-configuration.cc b/src/ic/handler-configuration.cc
index ece15ff24b9066158c85524ed0087f6804feb61c..ca49ed91db7b667fe3154a309e78130a9efe6d99 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 0447e017fbedae66eac2ad9637d53121a008f5b0..93939fa4702922f58e8e5bcc019e569f42ab198e 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -2300,10 +2300,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.
@@ -2314,7 +2322,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 a83a060337739878f258c50d8013d5ba6c2262d8..723a961521f26cdad66a484f39037f94109e2cac 100644
--- a/src/objects/map-inl.h
+++ b/src/objects/map-inl.h
@@ -590,6 +590,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 6914a51150f4235386f5dca7af0d8103bc64f9e2..8311850f82bc32b794873689789c510376f67233 100644
--- a/src/objects/map.h
+++ b/src/objects/map.h
@@ -422,6 +422,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

@@ -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 5de77fee9d2e5c76438b8612f29afc067bd02c13..7333bd59b99a618339413f0647562ed5ff5841d6 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -727,9 +727,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());
@@ -2390,6 +2387,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;
@@ -2730,20 +2741,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 39a240da4f3e601e8eea1a61dcab75369e51ac05..7f150822e9f224680fc4649a46f319ed97f9a171 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -567,7 +567,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 7fa94527f1002b6a3d17b9aa45211e51a51d7544..c12cbd4fcac2b110d875a1371d29ad54f48c8d71 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -1836,6 +1836,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));
@@ -1964,6 +1968,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

@@ -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

@@ -17,6 +17,7 @@ def main():
chromedriver_name = {
'darwin': 'chromedriver',
'win32': 'chromedriver.exe',
'linux': 'chromedriver',
'linux2': 'chromedriver'
}

View File

@@ -78,15 +78,20 @@ void StopTracing(gin_helper::Promise<base::FilePath> promise,
}
},
std::move(promise), *file_path);
if (file_path) {
auto* instance = TracingController::GetInstance();
if (!instance->IsTracing()) {
std::move(resolve_or_reject)
.Run(absl::make_optional(
"Failed to stop tracing - no trace in progress"));
} else if (file_path) {
auto split_callback = base::SplitOnceCallback(std::move(resolve_or_reject));
auto endpoint = TracingController::CreateFileEndpoint(
*file_path,
base::BindOnce(std::move(split_callback.first), absl::nullopt));
if (!TracingController::GetInstance()->StopTracing(endpoint)) {
if (!instance->StopTracing(endpoint)) {
std::move(split_callback.second)
.Run(absl::make_optional(
"Failed to stop tracing (was a trace in progress?)"));
.Run(absl::make_optional("Failed to stop tracing"));
}
} else {
std::move(resolve_or_reject)

View File

@@ -11,6 +11,7 @@
#include "content/public/browser/render_widget_host_view.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/native_browser_view.h"
#include "shell/browser/native_window.h"
namespace electron {
@@ -36,7 +37,11 @@ void AutofillDriver::ShowAutofillPopup(
v8::HandleScope scope(isolate);
auto* web_contents = api::WebContents::From(
content::WebContents::FromRenderFrameHost(render_frame_host_));
if (!web_contents || !web_contents->owner_window())
if (!web_contents)
return;
auto* owner_window = web_contents->owner_window();
if (!owner_window)
return;
auto* embedder = web_contents->embedder();
@@ -55,9 +60,23 @@ void AutofillDriver::ShowAutofillPopup(
embedder_frame_host = embedder->web_contents()->GetPrimaryMainFrame();
}
// Ensure that if the WebContents belongs to a BrowserView,
// the popup is positioned relative to the BrowserView's bounds.
for (NativeBrowserView* bv : owner_window->browser_views()) {
auto* iwc = bv->GetInspectableWebContents();
if (!iwc)
continue;
auto* awc = api::WebContents::From(iwc->GetWebContents());
if (awc == web_contents) {
auto bv_origin = bv->GetBounds().origin();
popup_bounds.Offset(gfx::Vector2dF(bv_origin.x(), bv_origin.y()));
break;
}
}
autofill_popup_->CreateView(render_frame_host_, embedder_frame_host, osr,
web_contents->owner_window()->content_view(),
popup_bounds);
owner_window->content_view(), popup_bounds);
autofill_popup_->SetItems(values, labels);
}

View File

@@ -152,6 +152,9 @@ class NativeWindow : public base::SupportsUserData,
virtual std::string GetAlwaysOnTopLevel() = 0;
virtual void SetActive(bool is_key) = 0;
virtual bool IsActive() const = 0;
virtual void RemoveChildWindow(NativeWindow* child) = 0;
virtual void AttachChildren() = 0;
virtual void DetachChildren() = 0;
#endif
// Ability to augment the window title for the screen readers.
@@ -382,6 +385,10 @@ class NativeWindow : public base::SupportsUserData,
int32_t window_id() const { return next_id_; }
void add_child_window(NativeWindow* child) {
child_windows_.push_back(child);
}
int NonClientHitTest(const gfx::Point& point);
void AddDraggableRegionProvider(DraggableRegionProvider* provider);
void RemoveDraggableRegionProvider(DraggableRegionProvider* provider);
@@ -422,6 +429,8 @@ class NativeWindow : public base::SupportsUserData,
FullScreenTransitionType fullscreen_transition_type_ =
FullScreenTransitionType::NONE;
std::list<NativeWindow*> child_windows_;
private:
std::unique_ptr<views::Widget> widget_;

View File

@@ -154,6 +154,12 @@ class NativeWindowMac : public NativeWindow,
void NotifyWindowLeaveFullScreen() override;
void SetActive(bool is_key) override;
bool IsActive() const override;
// Remove the specified child window without closing it.
void RemoveChildWindow(NativeWindow* child) override;
// Attach child windows, if the window is visible.
void AttachChildren() override;
// Detach window from parent without destroying it.
void DetachChildren() override;
void NotifyWindowWillEnterFullScreen();
void NotifyWindowWillLeaveFullScreen();

View File

@@ -473,14 +473,7 @@ void NativeWindowMac::Hide() {
return;
}
// Hide all children of the current window before hiding the window.
// components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
// expects this when window visibility changes.
if ([window_ childWindows]) {
for (NSWindow* child in [window_ childWindows]) {
[child orderOut:nil];
}
}
DetachChildren();
// Detach the window from the parent before.
if (parent())
@@ -600,6 +593,37 @@ bool NativeWindowMac::HandleDeferredClose() {
return false;
}
void NativeWindowMac::RemoveChildWindow(NativeWindow* child) {
child_windows_.remove_if([&child](NativeWindow* w) { return (w == child); });
[window_ removeChildWindow:child->GetNativeWindow().GetNativeNSWindow()];
}
void NativeWindowMac::AttachChildren() {
for (auto* child : child_windows_) {
auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow();
if ([child_nswindow parentWindow] == window_)
continue;
// Attaching a window as a child window resets its window level, so
// save and restore it afterwards.
NSInteger level = window_.level;
[window_ addChildWindow:child_nswindow ordered:NSWindowAbove];
[window_ setLevel:level];
}
}
void NativeWindowMac::DetachChildren() {
DCHECK(child_windows_.size() == [[window_ childWindows] count]);
// Hide all children before hiding/minimizing the window.
// NativeWidgetNSWindowBridge::NotifyVisibilityChangeDown()
// will DCHECK otherwise.
for (auto* child : child_windows_) {
[child->GetNativeWindow().GetNativeNSWindow() orderOut:nil];
}
}
void NativeWindowMac::SetFullScreen(bool fullscreen) {
if (!has_frame() && !HasStyleMask(NSWindowStyleMaskTitled))
return;
@@ -1765,18 +1789,12 @@ void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
// Remove current parent window.
if ([window_ parentWindow])
[[window_ parentWindow] removeChildWindow:window_];
parent->RemoveChildWindow(this);
// Set new parent window.
// Note that this method will force the window to become visible.
if (parent && attach) {
// Attaching a window as a child window resets its window level, so
// save and restore it afterwards.
NSInteger level = window_.level;
[parent->GetNativeWindow().GetNativeNSWindow()
addChildWindow:window_
ordered:NSWindowAbove];
[window_ setLevel:level];
parent->add_child_window(this);
parent->AttachChildren();
}
}

View File

@@ -718,10 +718,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
}

View File

@@ -322,6 +322,9 @@ class NativeWindowViews : public NativeWindow,
// Handles unhandled keyboard messages coming back from the renderer process.
std::unique_ptr<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

@@ -239,6 +239,7 @@ using FullScreenTransitionState =
level_ = [window level];
shell_->SetWindowLevel(NSNormalWindowLevel);
shell_->UpdateWindowOriginalFrame();
shell_->DetachChildren();
}
- (void)windowDidMiniaturize:(NSNotification*)notification {
@@ -248,6 +249,7 @@ using FullScreenTransitionState =
- (void)windowDidDeminiaturize:(NSNotification*)notification {
[super windowDidDeminiaturize:notification];
shell_->AttachChildren();
shell_->SetWindowLevel(level_);
shell_->NotifyWindowRestore();
}

View File

@@ -4237,11 +4237,13 @@ describe('BrowserWindow module', () => {
const c = new BrowserWindow({ show: false, parent: w });
expect(c.getParentWindow()).to.equal(w);
});
it('adds window to child windows of parent', () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });
expect(w.getChildWindows()).to.deep.equal([c]);
});
it('removes from child windows of parent when window is closed', async () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });
@@ -4253,6 +4255,59 @@ describe('BrowserWindow module', () => {
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 });
const wShow = emittedOnce(w, 'show');
const cShow = emittedOnce(c, 'show');
w.show();
c.show();
await Promise.all([wShow, cShow]);
const minimized = emittedOnce(w, 'minimize');
w.minimize();
await minimized;
expect(w.isVisible()).to.be.false('parent is visible');
expect(c.isVisible()).to.be.false('child is visible');
const restored = emittedOnce(w, 'restore');
w.restore();
await restored;
expect(w.isVisible()).to.be.true('parent is visible');
expect(c.isVisible()).to.be.true('child is visible');
});
ifit(process.platform === 'darwin')('matches child window visibility when visibility changes', async () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });
const wShow = emittedOnce(w, 'show');
const cShow = emittedOnce(c, 'show');
w.show();
c.show();
await Promise.all([wShow, cShow]);
const minimized = emittedOnce(c, 'minimize');
c.minimize();
await minimized;
expect(c.isVisible()).to.be.false('child is visible');
const restored = emittedOnce(c, 'restore');
c.restore();
await restored;
expect(w.isVisible()).to.be.true('parent is visible');
expect(c.isVisible()).to.be.true('child is visible');
});
it('closes a grandchild window when a middle child window is destroyed', (done) => {
const w = new BrowserWindow();
@@ -4863,6 +4918,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

@@ -113,7 +113,7 @@ ifdescribe(!(['arm', 'arm64', 'ia32'].includes(process.arch)))('contentTracing',
});
it('rejects if no trace is happening', async () => {
await expect(contentTracing.stopRecording()).to.be.rejected();
await expect(contentTracing.stopRecording()).to.be.rejectedWith('Failed to stop tracing - no trace in progress');
});
});

View File

@@ -527,13 +527,13 @@
universal-user-agent "^6.0.0"
"@octokit/request@^6.0.0":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255"
integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==
version "6.2.5"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.5.tgz#7beef1065042998f7455973ef3f818e7b84d6ec2"
integrity sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==
dependencies:
"@octokit/endpoint" "^7.0.0"
"@octokit/request-error" "^3.0.0"
"@octokit/types" "^8.0.0"
"@octokit/types" "^9.0.0"
is-plain-object "^5.0.0"
node-fetch "^2.6.7"
universal-user-agent "^6.0.0"